From b8aa38b18d7f7ab78766d2be94e8738e503bacca Mon Sep 17 00:00:00 2001 From: wiseoldman95 Date: Wed, 6 May 2015 17:23:07 +0300 Subject: (duplicate) AI - Livestock escape fixed, water jumping fixed --- src/Mobs/Monster.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++------ src/Mobs/Monster.h | 10 +++++++ src/Mobs/Path.cpp | 25 ----------------- 3 files changed, 79 insertions(+), 34 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 37774b08f..df9c1f390 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -156,6 +156,11 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) if (m_Path == nullptr) { + if (!EnsureProperDestination(a_Chunk)) + { + StopMovingToPosition(); // Invalid chunks, probably world is loading or something, cancel movement. + return false; + } m_PathFinderDestination = m_FinalDestination; m_Path = new cPath(a_Chunk, GetPosition().Floor(), m_PathFinderDestination.Floor(), 20); } @@ -199,10 +204,12 @@ void cMonster::MoveToWayPoint(cChunk & a_Chunk) { if (m_JumpCoolDown == 0) { - // We're not moving (or barely moving), and waypoint is above us, it means we are hitting something and we should jump. - if ((GetSpeedX() < 0.1) && (GetSpeedZ() < 0.1) && DoesPosYRequireJump(FloorC(m_NextWayPointPosition.y))) + if (DoesPosYRequireJump(FloorC(m_NextWayPointPosition.y))) { - if (IsOnGround() || IsSwimming()) + if ( + (IsOnGround() && (GetSpeedX() == 0) && (GetSpeedY() == 0)) || + (IsSwimming() && (m_GiveUpCounter < 15)) + ) { m_bOnGround = false; m_JumpCoolDown = 20; @@ -252,6 +259,63 @@ void cMonster::MoveToWayPoint(cChunk & a_Chunk) +bool cMonster::EnsureProperDestination(cChunk & a_Chunk) +{ + cChunk * Chunk = a_Chunk.GetNeighborChunk(m_FinalDestination.x, m_FinalDestination.z); + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + int RelX = m_FinalDestination.x - Chunk->GetPosX() * cChunkDef::Width; + int RelZ = m_FinalDestination.z - Chunk->GetPosZ() * cChunkDef::Width; + if ((Chunk == nullptr) || !Chunk->IsValid()) + { + return false; + } + + // If destination in the air, go down to the lowest air block. + while (m_FinalDestination.y > 0) + { + Chunk->GetBlockTypeMeta(RelX, m_FinalDestination.y - 1, RelZ, BlockType, BlockMeta); + if (cBlockInfo::IsSolid(BlockType)) + { + break; + } + m_FinalDestination.y -= 1; + } + + + // If destination in water, go up to the highest water block. + // If destination in solid, go up to first air block. + bool InWater = false; + while (m_FinalDestination.y < cChunkDef::Height) + { + Chunk->GetBlockTypeMeta(RelX, m_FinalDestination.y, RelZ, BlockType, BlockMeta); + if (BlockType == E_BLOCK_STATIONARY_WATER) + { + InWater = true; + } + else if (cBlockInfo::IsSolid(BlockType)) + { + InWater = false; + } + else + { + break; + } + m_FinalDestination.y += 1; + } + if (InWater) + { + m_FinalDestination.y -= 1; + } + + + return true; +} + + + + + void cMonster::MoveToPosition(const Vector3d & a_Position) { m_FinalDestination = a_Position; @@ -292,7 +356,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) if (m_Health <= 0) { - // The mob is dead, but we're still animating the "puff" they leave when they die + // The mob is dead, but we're still animating the "puff" they leave when they die. m_DestroyTimer += a_Dt; if (m_DestroyTimer > std::chrono::seconds(1)) { @@ -310,7 +374,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) m_Target = nullptr; } - // Process the undead burning in daylight + // Process the undead burning in daylight. HandleDaylightBurning(*Chunk, WouldBurnAt(GetPosition(), *Chunk)); if (TickPathFinding(*Chunk)) { @@ -1121,7 +1185,3 @@ cMonster::eFamily cMonster::GetMobFamily(void) const { return FamilyFromType(m_MobType); } - - - - diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index c7f38c9f7..a2295777a 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -203,8 +203,18 @@ protected: Returns if a path is ready, and therefore if the mob should move to m_NextWayPointPosition */ bool TickPathFinding(cChunk & a_Chunk); + + /** Move in a straight line to the next waypoint in the path, will jump if needed. */ void MoveToWayPoint(cChunk & a_Chunk); + /** Ensures the destination is not buried underground or under water. Also ensures the destination is not in the air. + Only the Y coordinate of m_FinalDestination might be changed. + 1. If m_FinalDestination is the position of a water block, m_FinalDestination's Y will be modified to point to the heighest water block in the pool in the current column. + 2. If m_FinalDestination is the position of a solid, m_FinalDestination's Y will be modified to point to the first airblock above the solid in the current column. + 3. If m_FinalDestination is the position of an air block, Y will keep decreasing until hitting either a solid or water. + Now either 1 or 2 is performed. */ + bool EnsureProperDestination(cChunk & a_Chunk); + /** Resets a pathfinding task, be it due to failure or something else Resets the pathfinder. If m_IsFollowingPath is true, TickPathFinding starts a brand new path. Should only be called by the pathfinder, cMonster::Tick or StopMovingToPosition. */ diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index 84d888bf2..ebfb5b630 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -54,31 +54,6 @@ cPath::cPath( return; } - // If destination in water, set water surface as destination. - cChunk * Chunk = m_Chunk->GetNeighborChunk(m_Destination.x, m_Destination.z); - if ((Chunk != nullptr) && Chunk->IsValid()) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - int RelX = m_Destination.x - Chunk->GetPosX() * cChunkDef::Width; - int RelZ = m_Destination.z - Chunk->GetPosZ() * cChunkDef::Width; - bool inwater = false; - for (;;) - { - Chunk->GetBlockTypeMeta(RelX, m_Destination.y, RelZ, BlockType, BlockMeta); - if (BlockType != E_BLOCK_STATIONARY_WATER) - { - break; - } - inwater = true; - m_Destination+=Vector3d(0, 1, 0); - } - if (inwater) - { - m_Destination+=Vector3d(0, -1, 0); - } - } - m_Status = ePathFinderStatus::CALCULATING; m_StepsLeft = a_MaxSteps; -- cgit v1.2.3 From 7771091099fad43025c63694ccf9362cce384aa8 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 6 May 2015 17:26:59 +0100 Subject: Actually empty the open list --- src/Mobs/Path.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index 84d888bf2..60f88f525 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -245,7 +245,7 @@ void cPath::FinishCalculation() } m_Map.clear(); - m_OpenList.empty(); + m_OpenList = std::priority_queue, compareHeuristics>{}; } -- cgit v1.2.3 From 753dfb950a6ec880af47ac7c1b0d6d142a138eac Mon Sep 17 00:00:00 2001 From: wiseoldman95 Date: Wed, 6 May 2015 16:52:37 +0300 Subject: AI - Better shade cover --- src/Mobs/Monster.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index df9c1f390..c799e9394 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -378,7 +378,15 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) HandleDaylightBurning(*Chunk, WouldBurnAt(GetPosition(), *Chunk)); if (TickPathFinding(*Chunk)) { - if (m_BurnsInDaylight && WouldBurnAt(m_NextWayPointPosition, *Chunk->GetNeighborChunk(FloorC(m_NextWayPointPosition.x), FloorC(m_NextWayPointPosition.z))) && !IsOnFire() && (m_TicksSinceLastDamaged == 100)) + /* If I burn in daylight, and I won't burn where I'm standing, and I'll burn in my next position, and at least one of those is true: + 1. I am idle + 2. I was not hurt by a player recently. + Then STOP. */ + if ( + m_BurnsInDaylight && ((m_TicksSinceLastDamaged == 100) || (m_EMState == IDLE)) && + WouldBurnAt(m_NextWayPointPosition, *Chunk->GetNeighborChunk(FloorC(m_NextWayPointPosition.x), FloorC(m_NextWayPointPosition.z))) && + !WouldBurnAt(GetPosition(), *Chunk->GetNeighborChunk(FloorC(GetPosition().x), FloorC(GetPosition().z))) + ) { // If we burn in daylight, and we would burn at the next step, and we won't burn where we are right now, and we weren't provoked recently: StopMovingToPosition(); -- cgit v1.2.3 From 40af96b100e88faaad451028856c46b0ba15de11 Mon Sep 17 00:00:00 2001 From: wiseoldman95 Date: Wed, 6 May 2015 17:02:50 +0300 Subject: AI - Safer WouldBurnAt() --- src/Mobs/Monster.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index c799e9394..84f58ff85 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -383,9 +383,9 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) 2. I was not hurt by a player recently. Then STOP. */ if ( - m_BurnsInDaylight && ((m_TicksSinceLastDamaged == 100) || (m_EMState == IDLE)) && - WouldBurnAt(m_NextWayPointPosition, *Chunk->GetNeighborChunk(FloorC(m_NextWayPointPosition.x), FloorC(m_NextWayPointPosition.z))) && - !WouldBurnAt(GetPosition(), *Chunk->GetNeighborChunk(FloorC(GetPosition().x), FloorC(GetPosition().z))) + m_BurnsInDaylight && ((m_TicksSinceLastDamaged >= 100) || (m_EMState == IDLE)) && + WouldBurnAt(m_NextWayPointPosition, *Chunk) && + !WouldBurnAt(GetPosition(), *Chunk) ) { // If we burn in daylight, and we would burn at the next step, and we won't burn where we are right now, and we weren't provoked recently: @@ -1170,6 +1170,11 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn) bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) { + cChunk * Chunk = a_Chunk.GetNeighborChunk(FloorC(m_NextWayPointPosition.x), FloorC(m_NextWayPointPosition.z)); + if ((Chunk == nullptr) || (!Chunk->IsValid())) + { + return false; + } int RelX = FloorC(a_Location.x) - a_Chunk.GetPosX() * cChunkDef::Width; int RelY = FloorC(a_Location.y); int RelZ = FloorC(a_Location.z) - a_Chunk.GetPosZ() * cChunkDef::Width; -- cgit v1.2.3 From aa3450808d237d0a8c6e8cbf02c59759f951a6d1 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 6 May 2015 19:11:25 +0100 Subject: Properly fix the docs for FindAndDoWithPlayer. Removed F accidentially added. Made the two FindAndDoWithPlayers documentation consistent. --- MCServer/Plugins/APIDump/APIDesc.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index ad86837e3..79340434d 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -8,7 +8,7 @@ g_APIDesc = { Classes = -F --[[ + --[[ -- What the APIDump plugin understands / how to document stuff: ExampleClassName = { @@ -2046,7 +2046,7 @@ a_Player:OpenWindow(Window); BroadcastChatSuccess = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtSuccess. Use for success messages." }, BroadcastChatWarning = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtWarning. Use for concerning events, such as plugin reload etc." }, CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil.

NOTEThis function is currently unsafe, do not use!" }, - FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided.
This function is not case-sensitive." }, + FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "bool", Notes = "Calls the given callback function for the player with the name best matching the name string provided.
This function is case-insensitive and will match partial names.
Returns false if player not found or there is ambiguity, true otherwise. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}})
" }, DoWithPlayerByUUID = { Params = "PlayerUUID, CallbackFunction", Return = "bool", Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}})
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature:
function Callback({{cPlayer|cPlayer}})
" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature:
function Callback({{cWorld|cWorld}})
" }, @@ -2330,7 +2330,7 @@ local CompressedString = cStringCompression.CompressStringGZIP("DataToCompress") { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sets the block at the specified coords, without waking up the simulators or replacing the block entities for the previous block type. Do not use if the block being replaced has a block entity tied to it!" }, { Params = "{{Vector3i|BlockCoords}}, BlockType, BlockMeta", Return = "", Notes = "Sets the block at the specified coords, without waking up the simulators or replacing the block entities for the previous block type. Do not use if the block being replaced has a block entity tied to it!" }, }, - FindAndDoWithPlayer = { Params = "PlayerNameHint, CallbackFunction", Return = "bool", Notes = "If there is a player of a name similar to the specified name (weighted-match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}})
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found. Note that the name matching is very loose, so it is a good idea to check the player name in the callback function." }, + FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "bool", Notes = "Calls the given callback function for the player with the name best matching the name string provided.
This function is case-insensitive and will match partial names.
Returns false if player not found or there is ambiguity, true otherwise. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}})
" }, ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature:
function Callback({{cBlockEntity|BlockEntity}})
The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." }, ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature:
function Callback({{cChestEntity|ChestEntity}})
The callback should return false or no value to continue with the next chest, or true to abort the enumeration." }, ForEachEntity = { Params = "CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature:
function Callback({{cEntity|Entity}})
The callback should return false or no value to continue with the next entity, or true to abort the enumeration." }, -- cgit v1.2.3 From 448df85e569e85e1b4da4eac685950273f30ae1f Mon Sep 17 00:00:00 2001 From: tycho Date: Sat, 21 Mar 2015 17:17:26 +0000 Subject: Added support for additional data in the ParticleEffect Packet Also started refactoring how broadcasts are handled --- src/Bindings/LuaState.cpp | 41 ++++++++++++++++++++++++++ src/Bindings/LuaState.h | 6 ++++ src/Bindings/ManualBindings.cpp | 58 ++++++++++++++++++++++++++++++++++++- src/Broadcaster.cpp | 47 ++++++++++++++++++++++++++++++ src/Broadcaster.h | 20 +++++++++++++ src/CMakeLists.txt | 2 ++ src/Chunk.h | 6 ++-- src/ChunkMap.cpp | 22 ++++++++++++++ src/ChunkMap.h | 3 ++ src/ClientHandle.cpp | 9 ++++++ src/ClientHandle.h | 2 ++ src/Entities/Floater.cpp | 6 ++-- src/Mobs/Wolf.cpp | 5 ++-- src/Protocol/Protocol.h | 3 ++ src/Protocol/Protocol17x.cpp | 10 +++++++ src/Protocol/Protocol17x.h | 1 + src/Protocol/Protocol18x.cpp | 44 ++++++++++++++++++++++++++++ src/Protocol/Protocol18x.h | 1 + src/Protocol/ProtocolRecognizer.cpp | 11 +++++++ src/Protocol/ProtocolRecognizer.h | 1 + src/World.cpp | 24 +++++++++------ src/World.h | 7 ++++- 22 files changed, 310 insertions(+), 19 deletions(-) create mode 100644 src/Broadcaster.cpp create mode 100644 src/Broadcaster.h diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index ed31e678f..f574dbe26 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1133,6 +1133,23 @@ void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, pClientHandle & a_ReturnedVal) +{ + if (lua_isnil(m_LuaState, a_StackPos)) + { + a_ReturnedVal = nullptr; + return; + } + tolua_Error err; + if (tolua_isusertype(m_LuaState, a_StackPos, "cClientHandle", false, &err)) + { + a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos))); + } +} + + + + bool cLuaState::CallFunction(int a_NumResults) { ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first @@ -1415,6 +1432,30 @@ bool cLuaState::CheckParamEnd(int a_Param) +bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) +{ + ASSERT(IsValid()); + + tolua_Error tolua_err; + return tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err); +} + + + + + +bool cLuaState::IsParamNumber(int a_Param) +{ + ASSERT(IsValid()); + + tolua_Error tolua_err; + return tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err); +} + + + + + bool cLuaState::ReportErrors(int a_Status) { return ReportErrors(m_LuaState, a_Status); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 6bedbf5ec..3f2e828f3 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -76,6 +76,7 @@ typedef cPluginManager * pPluginManager; typedef cRoot * pRoot; typedef cScoreboard * pScoreboard; typedef cWorld * pWorld; +typedef cClientHandle * pClientHandle; @@ -254,6 +255,7 @@ public: void GetStackValue(int a_StackPos, int & a_Value); void GetStackValue(int a_StackPos, pBlockArea & a_Value); void GetStackValue(int a_StackPos, pBoundingBox & a_Value); + void GetStackValue(int a_StackPos, pClientHandle & a_Value); void GetStackValue(int a_StackPos, pMapManager & a_Value); void GetStackValue(int a_StackPos, pPluginManager & a_Value); void GetStackValue(int a_StackPos, pRoot & a_Value); @@ -307,6 +309,10 @@ public: /** Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) */ bool CheckParamEnd(int a_Param); + bool IsParamUserType(int a_Param, AString a_UserType); + + bool IsParamNumber(int a_Param); + /** If the status is nonzero, prints the text on the top of Lua stack and returns true */ bool ReportErrors(int status); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f25800d5f..2fbff11d3 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -32,9 +32,10 @@ #include "../WorldStorage/SchematicFileSerializer.h" #include "../CompositeChat.h" #include "../StringCompression.h" +#include "../Broadcaster.h" - +#include // Better error reporting for Lua @@ -2009,6 +2010,60 @@ static int tolua_cPluginManager_FindPlugins(lua_State * tolua_S) +static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cWorld") || + !L.CheckParamString (2) || + !L.CheckParamNumber (3, 10) + ) + { + return 0; + } + + cPluginLua * Plugin = GetLuaPlugin(tolua_S); + if (Plugin == nullptr) + { + return 0; + } + + // Read the params: + cWorld * World = nullptr; + AString Name; + double PosX, PosY, PosZ, OffX, OffY, OffZ; + double ParticleData; + int ParticleAmmount; + L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmmount); + if (World == nullptr) + { + LOGWARNING("World:BroadcastParticleEffect(): invalid world parameter"); + L.LogStackTrace(); + return 0; + } + + std::array data; + + for (int i = 0; (i < 2) && L.IsParamNumber(11 + i); i++) + { + L.GetStackValue(11 + i, data[i]); + } + + cClientHandle * Exclude = nullptr; + + if (L.IsParamUserType(11, "cClientHandle")) + { + L.GetStackValue(11, Exclude); + } + World->GetBroadcaster().BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmmount, Exclude); + + return 0; +} + + + + + static int tolua_cWorld_ChunkStay(lua_State * tolua_S) { /* Function signature: @@ -3792,6 +3847,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWorld"); + tolua_function(tolua_S, "BroadcastParticleEffect", tolua_cWorld_BroadcastParticleEffect); tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay); tolua_function(tolua_S, "DoWithBlockEntityAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithBeaconAt", tolua_DoWithXYZ); diff --git a/src/Broadcaster.cpp b/src/Broadcaster.cpp new file mode 100644 index 000000000..7f2b65d09 --- /dev/null +++ b/src/Broadcaster.cpp @@ -0,0 +1,47 @@ + +#include "Globals.h" +#include "Broadcaster.h" +#include "World.h" +#include "Chunk.h" + +cBroadcaster::cBroadcaster(cWorld * a_World) : + m_World(a_World) +{ +} + + +void cBroadcaster::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) +{ + m_World->DoWithChunkAt(a_Src, + [=](cChunk & a_Chunk) -> bool + { + for (auto&& client : a_Chunk.GetAllClients()) + { + if (client == a_Exclude) + { + continue; + } + client->SendParticleEffect(a_ParticleName, a_Src.x, a_Src.y, a_Src.z, a_Offset.x, a_Offset.y, a_Offset.z, a_ParticleData, a_ParticleAmount); + }; + return true; + }); +} + + +void cBroadcaster::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data, cClientHandle * a_Exclude) +{ + m_World->DoWithChunkAt(a_Src, + [=](cChunk & a_Chunk) -> bool + { + for (auto && client : a_Chunk.GetAllClients()) + { + if (client == a_Exclude) + { + continue; + } + client->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data); + }; + return true; + }); +} + diff --git a/src/Broadcaster.h b/src/Broadcaster.h new file mode 100644 index 000000000..27d35fe4d --- /dev/null +++ b/src/Broadcaster.h @@ -0,0 +1,20 @@ + +class cWorld; + +#include + +class cBroadcaster +{ + +public: + + cBroadcaster(cWorld * a_World); + + void BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr); + + void BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data, cClientHandle * a_Exclude = nullptr); + +private: + cWorld * m_World; + +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e04e6311f..fd28f3787 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ SET (SRCS BlockArea.cpp BlockID.cpp BlockInfo.cpp + Broadcaster.cpp BoundingBox.cpp ByteBuffer.cpp ChatColor.cpp @@ -77,6 +78,7 @@ SET (HDRS BlockInServerPluginInterface.h BlockInfo.h BlockTracer.h + Broadcaster.h BoundingBox.h BuildInfo.h.cmake ByteBuffer.h diff --git a/src/Chunk.h b/src/Chunk.h index e8c60a74b..58f6ba707 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -439,6 +439,9 @@ public: as at least one requests is active the chunk will be ticked). */ void SetAlwaysTicked(bool a_AlwaysTicked); + // Makes a copy of the list + cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } + private: friend class cChunkMap; @@ -530,9 +533,6 @@ private: /** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */ void WakeUpSimulators(void); - - // Makes a copy of the list - cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } /** Sends m_PendingSendBlocks to all clients */ void BroadcastPendingBlockChanges(void); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b84b8dc3d..edff6baf1 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -791,6 +791,28 @@ bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callb } +bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback) +{ + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ); + struct cCallBackWrapper : cChunkCallback + { + cCallBackWrapper(std::function a_InnerCallback) : + m_Callback(a_InnerCallback) + { + } + + virtual bool Item(cChunk * a_Chunk) + { + return m_Callback(*a_Chunk); + } + + private: + std::function m_Callback; + } callback(a_Callback); + return DoWithChunk(ChunkX, ChunkZ, callback); +} + diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 0fac79c84..e9f1b94c0 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -104,6 +104,9 @@ public: /** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */ bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); + /** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback **/ + bool DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback); + /** Wakes up simulators for the specified block */ void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 60a2f8873..b12ab419b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2374,6 +2374,15 @@ void cClientHandle::SendParticleEffect(const AString & a_ParticleName, float a_S +void cClientHandle::SendParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) +{ + m_Protocol->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data); +} + + + + + void cClientHandle::SendPickupSpawn(const cPickup & a_Pickup) { m_Protocol->SendPickupSpawn(a_Pickup); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 9e5287985..7992d6bc2 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -22,6 +22,7 @@ #include "ChunkSender.h" +#include @@ -177,6 +178,7 @@ public: // tolua_export void SendMapInfo (int a_ID, unsigned int a_Scale); void SendPaintingSpawn (const cPainting & a_Painting); void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); + void SendParticleEffect (const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data); void SendPickupSpawn (const cPickup & a_Pickup); void SendPlayerAbilities (void); void SendPlayerListAddPlayer (const cPlayer & a_Player); diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp index cf8dd6c6f..0c868270d 100644 --- a/src/Entities/Floater.cpp +++ b/src/Entities/Floater.cpp @@ -6,7 +6,7 @@ #include "Floater.h" #include "Player.h" #include "../ClientHandle.h" - +#include "Broadcaster.h" @@ -145,12 +145,12 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { LOGD("Started producing particles for floater %i", GetUniqueID()); m_ParticlePos.Set(GetPosX() + (-4 + m_World->GetTickRandomNumber(8)), GetPosY(), GetPosZ() + (-4 + m_World->GetTickRandomNumber(8))); - m_World->BroadcastParticleEffect("splash", (float) m_ParticlePos.x, (float) m_ParticlePos.y, (float) m_ParticlePos.z, 0, 0, 0, 0, 15); + m_World->GetBroadcaster().BroadcastParticleEffect("splash", static_cast(m_ParticlePos), Vector3f{}, 0, 15); } else if (m_CountDownTime < 20) { m_ParticlePos = (m_ParticlePos + (GetPosition() - m_ParticlePos) / 6); - m_World->BroadcastParticleEffect("splash", (float) m_ParticlePos.x, (float) m_ParticlePos.y, (float) m_ParticlePos.z, 0, 0, 0, 0, 15); + m_World->GetBroadcaster().BroadcastParticleEffect("splash", static_cast(m_ParticlePos), Vector3f{}, 0, 15); } m_CountDownTime--; diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index c66763f17..3c2ec1520 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -5,6 +5,7 @@ #include "../World.h" #include "../Entities/Player.h" #include "../Items/ItemHandler.h" +#include "Broadcaster.h" @@ -83,13 +84,13 @@ void cWolf::OnRightClicked(cPlayer & a_Player) SetIsTame(true); SetOwner(a_Player.GetName(), a_Player.GetUUID()); m_World->BroadcastEntityStatus(*this, esWolfTamed); - m_World->BroadcastParticleEffect("heart", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); + m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast(GetPosition()), Vector3f{}, 0, 5); } else { // Taming failed m_World->BroadcastEntityStatus(*this, esWolfTaming); - m_World->BroadcastParticleEffect("smoke", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); + m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast(GetPosition()), Vector3f{}, 0, 5); } } } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index d8399049e..3bca7551b 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -16,6 +16,8 @@ #include "../Map.h" #include "../ByteBuffer.h" +#include + @@ -98,6 +100,7 @@ public: virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; + virtual void SendParticleEffect (const AString & a_SoundName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) = 0; virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) = 0; virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) = 0; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 8e7d526ef..57631c37d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -804,6 +804,16 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr +void cProtocol172::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) +{ + // 1.72 doesn't support extra data + this->SendParticleEffect(a_ParticleName, a_Src.x, a_Src.y, a_Src.z, a_Offset.x, a_Offset.y, a_Offset.z, a_ParticleData, a_ParticleAmount); +} + + + + + void cProtocol172::SendPlayerListAddPlayer(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 1212cc325..773c39f87 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -99,6 +99,7 @@ public: virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 4429ca683..628d8f528 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -802,6 +802,50 @@ void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_Sr +void cProtocol180::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) +{ + ASSERT(m_State == 3); // In game mode? + int ParticleID = GetParticleID(a_ParticleName); + + cPacketizer Pkt(*this, 0x2A); + Pkt.WriteBEInt32(ParticleID); + Pkt.WriteBool(false); + Pkt.WriteBEFloat(a_Src.x); + Pkt.WriteBEFloat(a_Src.y); + Pkt.WriteBEFloat(a_Src.z); + Pkt.WriteBEFloat(a_Offset.x); + Pkt.WriteBEFloat(a_Offset.y); + Pkt.WriteBEFloat(a_Offset.z); + Pkt.WriteBEFloat(a_ParticleData); + Pkt.WriteBEInt32(a_ParticleAmount); + switch (ParticleID) + { + // iconcrack + case 36: + { + Pkt.WriteVarInt32(static_cast(a_Data[0])); + Pkt.WriteVarInt32(static_cast(a_Data[1])); + break; + } + // blockcrack + // blockdust + case 37: + case 38: + { + Pkt.WriteVarInt32(static_cast(a_Data[0])); + break; + } + default: + { + break; + } + } +} + + + + + void cProtocol180::SendPlayerListAddPlayer(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 9aa5ed827..21024d702 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -97,6 +97,7 @@ public: virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) override; virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 36f8bc791..e7f7a4526 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -439,6 +439,17 @@ void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, flo + +void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) +{ + ASSERT(m_Protocol != nullptr); + m_Protocol->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data); +} + + + + + void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting) { m_Protocol->SendPaintingSpawn(a_Painting); diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 13be9478f..6c2185d6d 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -81,6 +81,7 @@ public: virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; diff --git a/src/World.cpp b/src/World.cpp index 87209e4c2..6c2e31965 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -57,7 +57,7 @@ #include #endif - +#include "Broadcaster.h" @@ -1459,6 +1459,15 @@ bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback +bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback) +{ + return m_ChunkMap->DoWithChunkAt(a_BlockPos, a_Callback); +} + + + + + void cWorld::GrowTree(int a_X, int a_Y, int a_Z) { if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) @@ -2241,14 +2250,6 @@ void cWorld::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation -void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) -{ - m_ChunkMap->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount, a_Exclude); -} - - - - void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude) { @@ -3770,5 +3771,10 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch +cBroadcaster cWorld::GetBroadcaster() +{ + return cBroadcaster(this); +} + diff --git a/src/World.h b/src/World.h index 1de241f60..624262cd3 100644 --- a/src/World.h +++ b/src/World.h @@ -55,6 +55,7 @@ class cMobHeadEntity; class cCompositeChat; class cCuboid; class cSetChunkData; +class cBroadcaster; typedef std::list< cPlayer * > cPlayerList; @@ -243,7 +244,6 @@ public: void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); virtual void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) override; // tolua_export - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr); // tolua_export void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); @@ -610,6 +610,9 @@ public: /** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */ bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); + /** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback **/ + bool DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback); + void GrowTreeImage(const sSetBlockVector & a_Blocks); // tolua_begin @@ -828,6 +831,8 @@ public: This function allows nesting and task-concurrency (multiple separate tasks can request ticking and as long as at least one requests is active the chunk will be ticked). */ void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export + + cBroadcaster GetBroadcaster(); private: -- cgit v1.2.3 From 63af47832d37de7829bb2dbfe2df9b63045cf556 Mon Sep 17 00:00:00 2001 From: Tri125 Date: Wed, 6 May 2015 23:12:17 -0400 Subject: Fixed the sound issue with the MagmaCube -Name of the sound is correctly capitalized -Get the appropriate sound depending on its size --- src/Mobs/MagmaCube.cpp | 14 ++++++++++++-- src/Mobs/MagmaCube.h | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Mobs/MagmaCube.cpp b/src/Mobs/MagmaCube.cpp index 3e9abc108..e56cfa4b8 100644 --- a/src/Mobs/MagmaCube.cpp +++ b/src/Mobs/MagmaCube.cpp @@ -7,7 +7,7 @@ cMagmaCube::cMagmaCube(int a_Size) : - super("MagmaCube", mtMagmaCube, "mob.MagmaCube.big", "mob.MagmaCube.big", 0.6 * a_Size, 0.6 * a_Size), + super("MagmaCube", mtMagmaCube, Printf("mob.magmacube.%s", GetSizeName(a_Size).c_str()), Printf("mob.magmacube.%s", GetSizeName(a_Size).c_str()), 0.6 * a_Size, 0.6 * a_Size), m_Size(a_Size) { } @@ -27,4 +27,14 @@ void cMagmaCube::GetDrops(cItems & a_Drops, cEntity * a_Killer) - +const AString cMagmaCube::GetSizeName(int a_Size) const +{ + if (a_Size > 1) + { + return "big"; + } + else + { + return "small"; + } +} diff --git a/src/Mobs/MagmaCube.h b/src/Mobs/MagmaCube.h index d66ea423a..62dd83944 100644 --- a/src/Mobs/MagmaCube.h +++ b/src/Mobs/MagmaCube.h @@ -19,6 +19,10 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; int GetSize(void) const { return m_Size; } + + /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. + Returns either "big" or "small". */ + const AString GetSizeName(int a_Size) const; protected: -- cgit v1.2.3 From 9f6192687f84fc97c5f854c778f3b393965794ef Mon Sep 17 00:00:00 2001 From: Tri125 Date: Wed, 6 May 2015 23:29:36 -0400 Subject: Big Magma Cube can now spawn Following the same method as the Slime, Magma Cube can now spawn with the size of 1, 2 or 4. --- src/Mobs/MagmaCube.h | 2 +- src/Mobs/Monster.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mobs/MagmaCube.h b/src/Mobs/MagmaCube.h index 62dd83944..d4b3997da 100644 --- a/src/Mobs/MagmaCube.h +++ b/src/Mobs/MagmaCube.h @@ -26,7 +26,7 @@ public: protected: - /// Size of the MagmaCube, 1 .. 3, with 1 being the smallest + /// Size of the MagmaCube, 1, 2 and 4, with 1 being the smallest int m_Size; } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 37774b08f..e86570c77 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -886,7 +886,7 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) { case mtMagmaCube: { - toReturn = new cMagmaCube(Random.NextInt(2) + 1); + toReturn = new cMagmaCube(1 << Random.NextInt(3)); // Size 1, 2 or 4 break; } case mtSlime: -- cgit v1.2.3 From 429e5451670f27d4d2563711370a65d86f282119 Mon Sep 17 00:00:00 2001 From: Tri125 Date: Thu, 7 May 2015 11:39:47 -0400 Subject: Fixed #1893 Quartz ore now stack properly --- src/Items/ItemHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index dddd67cdd..6bcb5f27a 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -579,6 +579,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_MELON_SEEDS: return 64; case E_ITEM_MELON_SLICE: return 64; case E_ITEM_NETHER_BRICK: return 64; + case E_ITEM_NETHER_QUARTZ: return 64; case E_ITEM_NETHER_WART: return 64; case E_ITEM_PAINTING: return 64; case E_ITEM_PAPER: return 64; -- cgit v1.2.3 From ceac39c4cd496bfcae11451261f040ddaca220f5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 7 May 2015 22:35:02 +0200 Subject: Added Lua C API checks in Debug builds. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76b91e642..2bb780eba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,9 @@ endif() # The Expat library is linked in statically, make the source files aware of that: add_definitions(-DXML_STATIC) +# Let Lua use additional checks on its C API. This is only compiled into Debug builds: +add_definitions(-DLUA_USE_APICHECK) + # Self Test Mode enables extra checks at startup if(${SELF_TEST}) add_definitions(-DSELF_TEST) -- cgit v1.2.3 From fee690a3d1412860b19447b2b390d3521adae7c6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 7 May 2015 23:02:18 +0200 Subject: Fixed inter-plugin calls. When an inter-plugin call failed due to function not found, the server would maul the LuaState and "yield". Fixes #1959. --- MCServer/Plugins/Debuggers/Debuggers.lua | 28 ++++++++++------------------ src/Bindings/LuaState.cpp | 13 ++++--------- src/Bindings/ManualBindings.cpp | 5 +++++ 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index bffc6e844..a49f8b5a6 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -54,7 +54,7 @@ function Initialize(a_Plugin) -- TestBlockAreas() -- TestSQLiteBindings() -- TestExpatBindings() - -- TestPluginCalls() + TestPluginCalls() TestBlockAreasString() TestStringBase64() @@ -157,26 +157,18 @@ function TestPluginCalls() -- The Split parameter should be a table, but it is not used in that function anyway, -- so we can get away with passing nil to it. - -- Use the old, deprecated and unsafe method: - local Core = cPluginManager:Get():GetPlugin("Core") - if (Core ~= nil) then - LOGINFO("Calling Core::ReturnColorFromChar() the old-fashioned way...") - local Gray = Core:Call("ReturnColorFromChar", nil, "8") - if (Gray ~= cChatColor.Gray) then - LOGWARNING("Call failed, exp " .. cChatColor.Gray .. ", got " .. (Gray or "")) - else - LOGINFO("Call succeeded") - end - end - - -- Use the new method: - LOGINFO("Calling Core::ReturnColorFromChar() the recommended way...") - local Gray = cPluginManager:CallPlugin("Core", "ReturnColorFromChar", nil, "8") + LOG("Debuggers: Calling NoSuchPlugin.FnName()...") + cPluginManager:CallPlugin("NoSuchPlugin", "FnName", "SomeParam") + LOG("Debuggers: Calling Core.NoSuchFunction()...") + cPluginManager:CallPlugin("Core", "NoSuchFunction", "SomeParam") + LOG("Debuggers: Calling Core.ReturnColorFromChar(..., \"8\")...") + local Gray = cPluginManager:CallPlugin("Core", "ReturnColorFromChar", "split", "8") if (Gray ~= cChatColor.Gray) then - LOGWARNING("Call failed, exp " .. cChatColor.Gray .. ", got " .. (Gray or "")) + LOGWARNING("Debuggers: Call failed, exp " .. cChatColor.Gray .. ", got " .. (Gray or "")) else - LOGINFO("Call succeeded") + LOG("Debuggers: Call succeeded") end + LOG("Debuggers: Inter-plugin calls done.") end diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index f574dbe26..9c1e2865c 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1535,7 +1535,7 @@ int cLuaState::CallFunctionWithForeignParams( if (!PushFunction(a_FunctionName.c_str())) { LOGWARNING("Function '%s' not found", a_FunctionName.c_str()); - lua_pop(m_LuaState, 2); + lua_settop(m_LuaState, OldTop); return -1; } @@ -1543,7 +1543,7 @@ int cLuaState::CallFunctionWithForeignParams( if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0) { // Something went wrong, fix the stack and exit - lua_pop(m_LuaState, 2); + lua_settop(m_LuaState, OldTop); m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); return -1; @@ -1554,13 +1554,8 @@ int cLuaState::CallFunctionWithForeignParams( if (ReportErrors(s)) { LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str()); - // Fix the stack. - // We don't know how many values have been pushed, so just get rid of any that weren't there initially - int CurTop = lua_gettop(m_LuaState); - if (CurTop > OldTop) - { - lua_pop(m_LuaState, CurTop - OldTop); - } + // Reset the stack: + lua_settop(m_LuaState, OldTop); // Reset the internal checking mechanisms: m_NumCurrentFunctionArgs = -1; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 2fbff11d3..20042a780 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1988,6 +1988,11 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) { return 0; } + if (Callback.m_NumReturns < 0) + { + // The call has failed, there are zero return values. Do NOT return negative number (Lua considers that a "yield") + return 0; + } return Callback.m_NumReturns; } -- cgit v1.2.3 From 0d003a2d2a8807983f23372dd15eabd403cd4b1c Mon Sep 17 00:00:00 2001 From: Woazboat Date: Wed, 29 Apr 2015 00:14:42 +0200 Subject: Changed Tracer::m_NormalTable to static array Was previously instantiated for every trace --- src/Tracer.cpp | 27 ++++++++++++++++++++------- src/Tracer.h | 4 +++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/Tracer.cpp b/src/Tracer.cpp index e604f4a5b..bd5fcebc5 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -13,16 +13,29 @@ +const std::array& cTracer::m_NormalTable(void) +{ + static std::array* table = + new std::array + { + { + Vector3f(-1, 0, 0), // 1: -x + Vector3f( 0, 0, -1), // 2: -z + Vector3f( 1, 0, 0), // 3: +x + Vector3f( 0, 0, 1), // 4: +z + Vector3f( 0, 1, 0), // 5: +y + Vector3f( 0, -1, 0) // 6: -y + } + }; + + return *table; +}; + + cTracer::cTracer(cWorld * a_World): m_World(a_World) { - m_NormalTable[0].Set(-1, 0, 0); - m_NormalTable[1].Set( 0, 0, -1); - m_NormalTable[2].Set( 1, 0, 0); - m_NormalTable[3].Set( 0, 0, 1); - m_NormalTable[4].Set( 0, 1, 0); - m_NormalTable[5].Set( 0, -1, 0); } @@ -241,7 +254,7 @@ bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int int Normal = GetHitNormal(a_Start, End, pos); if (Normal > 0) { - HitNormal = m_NormalTable[Normal-1]; + HitNormal = m_NormalTable()[Normal - 1]; } return true; } diff --git a/src/Tracer.h b/src/Tracer.h index ec87d449e..cf54fa66c 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -3,6 +3,8 @@ #include "Vector3.h" +#include + @@ -64,7 +66,7 @@ private: float SigNum( float a_Num); cWorld* m_World; - Vector3f m_NormalTable[6]; + static const std::array & m_NormalTable(void); Vector3f dir; Vector3f tDelta; -- cgit v1.2.3 From c74bfc35d61022c1d1e660935601d461b39b8b88 Mon Sep 17 00:00:00 2001 From: Woazboat Date: Tue, 28 Apr 2015 02:47:36 +0200 Subject: Check for zero length vector in Trace Added hasNonZeroLength member function to Vector3 --- src/Tracer.cpp | 14 ++++++++++---- src/Vector3.h | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Tracer.cpp b/src/Tracer.cpp index bd5fcebc5..38968bc61 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -69,6 +69,9 @@ float cTracer::SigNum(float a_Num) void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) { + // Since this method should only be called by Trace, zero length vectors should already have been taken care of + ASSERT(a_Direction.HasNonZeroLength()); + // calculate the direction of the ray (linear algebra) dir = a_Direction; @@ -78,10 +81,8 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) step.z = (int) SigNum(dir.z); // normalize the direction vector - if (dir.SqrLength() > 0.f) - { - dir.Normalize(); - } + dir.Normalize(); + // how far we must move in the ray direction before // we encounter a new voxel in x-direction @@ -151,6 +152,11 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance, bool a_LineOfSight) { + if (!a_Direction.HasNonZeroLength()) + { + return false; + } + if ((a_Start.y < 0) || (a_Start.y >= cChunkDef::Height)) { LOGD("%s: Start Y is outside the world (%.2f), not tracing.", __FUNCTION__, a_Start.y); diff --git a/src/Vector3.h b/src/Vector3.h index 36f277ba4..a42003aae 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -78,6 +78,11 @@ public: ); } + inline bool HasNonZeroLength(void) const + { + return ((x != 0) || (y != 0) || (z != 0)); + } + inline double Length(void) const { return sqrt(static_cast(x * x + y * y + z * z)); -- cgit v1.2.3 From 8a50918d2a58a84111567d73949fe67b9424c660 Mon Sep 17 00:00:00 2001 From: Woazboat Date: Tue, 28 Apr 2015 02:51:21 +0200 Subject: Tracer::signum function now returns int convert c style casts to c++ static casts Changed fabs() to std::abs() --- src/SetChunkData.cpp | 2 +- src/Tracer.cpp | 49 ++++++++++++++++++++++++++----------------------- src/Tracer.h | 3 ++- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index e5afd96ed..7549b0dbf 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -103,7 +103,7 @@ void cSetChunkData::CalculateHeightMap(void) int index = cChunkDef::MakeIndexNoCheck(x, y, z); if (m_BlockTypes[index] != E_BLOCK_AIR) { - m_HeightMap[x + z * cChunkDef::Width] = (HEIGHTTYPE)y; + m_HeightMap[x + z * cChunkDef::Width] = static_cast(y); break; } } // for y diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 38968bc61..b6b0fd634 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -12,6 +12,8 @@ +const float FLOAT_EPSILON = 0.0001f; // TODO: Stash this in some header where it can be reused + const std::array& cTracer::m_NormalTable(void) { @@ -50,7 +52,7 @@ cTracer::~cTracer() -float cTracer::SigNum(float a_Num) +int cTracer::SigNum(float a_Num) { if (a_Num < 0.f) { @@ -76,9 +78,10 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) dir = a_Direction; // decide which direction to start walking in - step.x = (int) SigNum(dir.x); - step.y = (int) SigNum(dir.y); - step.z = (int) SigNum(dir.z); + step.x = SigNum(dir.x); + step.y = SigNum(dir.y); + step.z = SigNum(dir.z); + // normalize the direction vector dir.Normalize(); @@ -89,7 +92,7 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) // same but y-direction if (dir.x != 0.f) { - tDelta.x = 1 / fabs(dir.x); + tDelta.x = 1 / std::abs(dir.x); } else { @@ -97,7 +100,7 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) } if (dir.y != 0.f) { - tDelta.y = 1 / fabs(dir.y); + tDelta.y = 1 / std::abs(dir.y); } else { @@ -105,44 +108,45 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) } if (dir.z != 0.f) { - tDelta.z = 1 / fabs(dir.z); + tDelta.z = 1 / std::abs(dir.z); } else { tDelta.z = 0; } + // start voxel coordinates - pos.x = (int)floorf(a_Start.x); - pos.y = (int)floorf(a_Start.y); - pos.z = (int)floorf(a_Start.z); + pos.x = static_cast(floorf(a_Start.x)); + pos.y = static_cast(floorf(a_Start.y)); + pos.z = static_cast(floorf(a_Start.z)); // calculate distance to first intersection in the voxel we start from if (dir.x < 0) { - tMax.x = ((float)pos.x - a_Start.x) / dir.x; + tMax.x = (static_cast(pos.x) - a_Start.x) / dir.x; } else { - tMax.x = (((float)pos.x + 1) - a_Start.x) / dir.x; + tMax.x = (static_cast(pos.x + 1) - a_Start.x) / dir.x; // TODO: Possible division by zero } if (dir.y < 0) { - tMax.y = ((float)pos.y - a_Start.y) / dir.y; + tMax.y = (static_cast(pos.y) - a_Start.y) / dir.y; } else { - tMax.y = (((float)pos.y + 1) - a_Start.y) / dir.y; + tMax.y = (static_cast(pos.y + 1) - a_Start.y) / dir.y; // TODO: Possible division by zero } if (dir.z < 0) { - tMax.z = ((float)pos.z - a_Start.z) / dir.z; + tMax.z = (static_cast(pos.z) - a_Start.z) / dir.z; } else { - tMax.z = (((float)pos.z + 1) - a_Start.z) / dir.z; + tMax.z = (static_cast(pos.z + 1) - a_Start.z) / dir.z; // TODO: Possible division by zero } } @@ -165,18 +169,18 @@ bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int SetValues(a_Start, a_Direction); - Vector3f End = a_Start + (dir * (float)a_Distance); + Vector3f End = a_Start + (dir * static_cast(a_Distance)); if (End.y < 0) { - float dist = -a_Start.y / dir.y; + float dist = -a_Start.y / dir.y; // No division by 0 possible End = a_Start + (dir * dist); } // end voxel coordinates - end1.x = (int)floorf(End.x); - end1.y = (int)floorf(End.y); - end1.z = (int)floorf(End.z); + end1.x = static_cast(floorf(End.x)); + end1.y = static_cast(floorf(End.y)); + end1.z = static_cast(floorf(End.z)); // check if first is occupied if (pos.Equals(end1)) @@ -314,8 +318,7 @@ int cTracer::intersect3D_SegmentPlane(const Vector3f & a_Origin, const Vector3f float D = a_PlaneNormal.Dot(u); // dot(Pn.n, u); float N = -(a_PlaneNormal.Dot(w)); // -dot(a_Plane.n, w); - const float EPSILON = 0.0001f; - if (fabs(D) < EPSILON) + if (std::abs(D) < FLOAT_EPSILON) { // segment is parallel to plane if (N == 0.0) diff --git a/src/Tracer.h b/src/Tracer.h index cf54fa66c..31531719f 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -63,7 +63,8 @@ private: /// Return 1 through 6 for the following block faces, repectively: -x, -z, x, z, y, -y int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); - float SigNum( float a_Num); + /// Signum function + int SigNum( float a_Num); cWorld* m_World; static const std::array & m_NormalTable(void); -- cgit v1.2.3 From 689fe6041c746d608330700160d3a71fb182be0b Mon Sep 17 00:00:00 2001 From: Woazboat Date: Tue, 28 Apr 2015 02:54:45 +0200 Subject: Changed Vector3 Equals function to avoid using memcmp --- src/Vector3.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index a42003aae..6164721da 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -126,11 +126,7 @@ public: { // Perform a bitwise comparison of the contents - we want to know whether this object is exactly equal // To perform EPS-based comparison, use the EqualsEps() function - return ( - (memcmp(&x, &a_Rhs.x, sizeof(x)) == 0) && - (memcmp(&y, &a_Rhs.y, sizeof(y)) == 0) && - (memcmp(&z, &a_Rhs.z, sizeof(z)) == 0) - ); + return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); } inline bool EqualsEps(const Vector3 & a_Rhs, T a_Eps) const -- cgit v1.2.3 From ed404bc2f6488a59da280697ad6c3a8ffcbab0fd Mon Sep 17 00:00:00 2001 From: Woazboat Date: Tue, 5 May 2015 22:21:07 +0200 Subject: Ignoring Clang warnings for strict float comparison in Vector::Equals() --- src/Vector3.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Vector3.h b/src/Vector3.h index 6164721da..d454fda06 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -124,9 +124,19 @@ public: inline bool Equals(const Vector3 & a_Rhs) const { - // Perform a bitwise comparison of the contents - we want to know whether this object is exactly equal + // Perform a strict comparison of the contents - we want to know whether this object is exactly equal // To perform EPS-based comparison, use the EqualsEps() function + +#ifndef __GNUC__ +#pragma clang diagnostics push +#pragma clang diagnostics ignored "-Wfloat-equal" +#endif + return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); + +#ifndef __GNUC__ +#pragma clang diagnostics pop +#endif } inline bool EqualsEps(const Vector3 & a_Rhs, T a_Eps) const -- cgit v1.2.3 From eb84ffe5a6eb4a79b91e58c263bf222496ad5afb Mon Sep 17 00:00:00 2001 From: Woazboat Date: Wed, 6 May 2015 01:53:28 +0200 Subject: Added float comparison warning overrides to Vector3::hasNonZeroLength --- src/Vector3.h | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index d454fda06..f116c07f6 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -80,7 +80,16 @@ public: inline bool HasNonZeroLength(void) const { + #ifndef __GNUC__ + #pragma clang diagnostics push + #pragma clang diagnostics ignored "-Wfloat-equal" + #endif + return ((x != 0) || (y != 0) || (z != 0)); + + #ifndef __GNUC__ + #pragma clang diagnostics pop + #endif } inline double Length(void) const @@ -127,16 +136,16 @@ public: // Perform a strict comparison of the contents - we want to know whether this object is exactly equal // To perform EPS-based comparison, use the EqualsEps() function -#ifndef __GNUC__ -#pragma clang diagnostics push -#pragma clang diagnostics ignored "-Wfloat-equal" -#endif + #ifndef __GNUC__ + #pragma clang diagnostics push + #pragma clang diagnostics ignored "-Wfloat-equal" + #endif return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); -#ifndef __GNUC__ -#pragma clang diagnostics pop -#endif + #ifndef __GNUC__ + #pragma clang diagnostics pop + #endif } inline bool EqualsEps(const Vector3 & a_Rhs, T a_Eps) const -- cgit v1.2.3 From 290bc2e37730c14df85b9ce9acd63611ca185434 Mon Sep 17 00:00:00 2001 From: wiseoldman95 Date: Fri, 8 May 2015 17:07:36 +0300 Subject: Spaces in cPath --- src/Mobs/Path.cpp | 1 + src/Mobs/Path.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index 6fc9e06c3..8abbc4cac 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" #include diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index 9e893f1d7..0d903adb6 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -1,3 +1,4 @@ + #pragma once /* Wanna use the pathfinder? Put this in your header file: -- cgit v1.2.3 From 05db1904f93fb2c218e1855924d4cddadba941ce Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 8 May 2015 15:13:58 +0100 Subject: Fixed syntax error --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 79340434d..2c26ccecc 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -8,6 +8,7 @@ g_APIDesc = { Classes = + { --[[ -- What the APIDump plugin understands / how to document stuff: ExampleClassName = -- cgit v1.2.3 From 3853db94e28b584678394ad468e1405036532e78 Mon Sep 17 00:00:00 2001 From: jammet Date: Fri, 8 May 2015 17:06:39 +0200 Subject: Corrected hopper recipe --- MCServer/crafting.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/crafting.txt b/MCServer/crafting.txt index 1e1f06156..e7d11ab92 100644 --- a/MCServer/crafting.txt +++ b/MCServer/crafting.txt @@ -304,7 +304,7 @@ Dropper = Cobblestone, 1:1, 2:1, 3:1, 1:2, 1:3, 3:2, 3:3 | Hopper, 2:2 Repeater = Stone, 1:2, 2:2, 3:2 | RedstoneTorchOn, 1:1, 3:1 | RedstoneDust, 2:1 Comparator = RedstoneTorchOn, 2:1, 1:2, 3:2 | NetherQuartz, 2:2 | Stone, 1:3, 2:3, 3:3 DaylightSensor = Glass, 1:1, 2:1, 3:1 | NetherQuartz, 1:2, 2:2, 3:2 | Woodslab, 1:3, 2:3, 3:3 -Hopper = Ironbars, 1:1, 3:1, 1:2, 3:2, 2:3 | Chest, 2:2 +Hopper = IronIngot, 1:1, 3:1, 1:2, 3:2, 2:3 | Chest, 2:2 Piston = Planks^-1, 1:1, 2:1, 3:1 | RedstoneDust, 2:3 | Cobblestone, 1:2, 3:2, 1:3, 3:3 | IronIngot, 2:2 StickyPiston = Piston, * | SlimeBall, * RedstoneLamp = RedstoneDust, 2:1, 1:2, 3:2, 2:3 | Glowstone, 2:2 -- cgit v1.2.3 From f410ce5987e5c8a667426baca42fe05a306dd48a Mon Sep 17 00:00:00 2001 From: Safwat Halaby Date: Thu, 7 May 2015 08:53:27 +0300 Subject: Added pre-commit hook to CONTRIBUTING.md Also added some other missing stuff. --- CONTRIBUTING.md | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f27451351..82f09b6bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,27 @@ -Code Stuff +Code Conventions ---------- +When contributing, you must follow our code conventions. Otherwise, the CI builds will automatically fail and your PR will not be merged until the non-conforming code is fixed. Due to this, we strongly advise you to run `src/CheckBasicStyle.lua` before commiting, it will perform various code style checks and warn you if your code does not conform to our conventions. `CheckBasicStyle.lua` can be configured to run automatically before every commit via a pre-commit hook, **this is highly recommended**. The way to do it is listed at the bottom of this file. + +Here are the conventions: + * We use the subset of C++11 supported by MSVC 2013 (ask if you think that something would be useful) + * All new public functions in all classes need documenting comments on what they do and what behavior they follow, use doxy-comments formatted as `/** Description */`. Do not use asterisks on additional lines in multi-line comments. + * Use spaces after the comment markers: `// Comment` instead of `//Comment`. A comment must be prefixed with two spaces if it's on the same line with code: + - `SomeFunction() // Note the two spaces prefixed to me and the space after the slashes.` + * All variable names and function names use CamelCase style. + - `ThisIsAProperFunction()` `This_is_bad()` `this_is_bad` `GoodVariableName` `badVariableName`. + * All member variables start with `m_`, all function parameters start with `a_`, all class names start with `c`. + - `class cMonster { int m_Health; int DecreaseHealth(int a_Amount); }` + * Put spaces after commas. `Vector3d(1, 2, 3)` instead of `Vector3d(1,2,3)` + * Put spaces before and after every operator. + - `a = b + c;` + - `if (a == b)` + * Keep individual functions spaced out by 5 empty lines, this enhances readability and makes navigation in the source file easier. + * Add those extra parentheses to conditions, especially in C++: + - `if ((a == 1) && ((b == 2) || (c == 3)))` instead of ambiguous `if (a == 1 && b == 2 || c == 3)` + - This helps prevent mistakes such as `if (a & 1 == 0)` + * * Use the provided wrappers for OS stuff: - Threading is done by inheriting from `cIsThread`, thread synchronization through `cCriticalSection`, `cSemaphore` and `cEvent`, file access and filesystem operations through the `cFile` class, high-precision timers through `cTimer`, high-precision sleep through `cSleep` * No magic numbers, use named constants: @@ -16,10 +36,6 @@ Code Stuff - `cPlayer:IsGameModeCreative()` instead of` (cPlayer:GetGameMode() == gmCreative)` (the player can also inherit the gamemode from the world, which the value-d condition doesn't catch) * Please use **tabs for indentation and spaces for alignment**. This means that if it's at line start, it's a tab; if it's in the middle of a line, it's a space * Alpha-sort stuff that makes sense alpha-sorting - long lists of similar items etc. - * Keep individual functions spaced out by 5 empty lines, this enhances readability and makes navigation in the source file easier. - * Add those extra parentheses to conditions, especially in C++ - - `if ((a == 1) && ((b == 2) || (c == 3)))` instead of ambiguous `if (a == 1 && b == 2 || c == 3)` - - This helps prevent mistakes such as `if (a & 1 == 0)` * White space is free, so use it freely - "freely" as in "plentifully", not "arbitrarily" * All `case` statements inside a `switch` need an extra indent. @@ -27,9 +43,22 @@ Code Stuff - The only exception: a `switch` statement with all `case` statements being a single short statement is allowed to use the short brace-less form. - These two rules really mean that indent is governed by braces * Add an empty last line in all source files (GCC and GIT can complain otherwise) - * All new public functions in all classes need documenting comments on what they do and what behavior they follow, use doxy-comments formatted as `/** Description */`. Do not use asterisks on additional lines in multi-line comments. - * Use spaces after the comment markers: `// Comment` instead of `//Comment` +Pre-commit hook +--------- +When contributing, the code conventions above *must* be followed. Otherwise, the CI builds will automatically fail and your PR will not be merged until the non-conforming code is fixed. It is highly recommended to set up a pre-commit hook which will check your code style before every commit. Here is how to do that: + + * Clone the repository as usual. + * Go to your `/.git/hooks` folder, create a text file named "pre-commit" there with the following contents: +``` +#!/usr/sh +src/CheckBasicStyle.lua 1>&2 -g +``` + * If on Linux/Unix, you need to give the newly created file an execute permission: `chmod +x .git/hooks/pre-commit` + * Lua must be installed. + * You're done. Now, `src/CheckBasicStyle.lua` will check the changed files before every commit. If a problem is found, it will point you to that problem and will cancel the commit. + +Note that the check script is not smart enough to catch everything, so not having any warnings does not necessarily imply that you followed the conventions fully. The other humans working on this will perform more checks before merging. Copyright --------- -- cgit v1.2.3 From 46bdc6c2c621a27c40e11c7af701f3ce50148e01 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 8 May 2015 17:20:59 +0100 Subject: Fix build URLs, now .tar.gz --- easyinstall.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easyinstall.sh b/easyinstall.sh index 40fa85cfe..15ca1d358 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -4,10 +4,10 @@ PLATFORM=$(uname -m) echo "Identifying platform: $PLATFORM" case $PLATFORM in - "i686") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x86/lastSuccessfulBuild/artifact/MCServer.tar" ;; - "x86_64") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x64/lastSuccessfulBuild/artifact/MCServer.tar" ;; + "i686") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x86/lastSuccessfulBuild/artifact/MCServer.tar.gz" ;; + "x86_64") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x64/lastSuccessfulBuild/artifact/MCServer.tar.gz" ;; # Assume that all arm devices are a raspi for now. - arm*) DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20armhf/lastSuccessfulBuild/artifact/MCServer/MCServer.tar" + arm*) DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20armhf/lastSuccessfulBuild/artifact/MCServer/MCServer.tar.gz" esac echo "Downloading precompiled binaries." -- cgit v1.2.3 From 60f150e77d933e7af99ff48d93fa1cfbad973449 Mon Sep 17 00:00:00 2001 From: Safwat Halaby Date: Fri, 8 May 2015 19:59:14 +0300 Subject: Update Contributing.MD Double space is rendering as a single space so I changed the comment line a bit, the new version is clearer anyway. Added an exception to CamelCase (single letter vars) --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 82f09b6bf..4e57e6efb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,8 @@ Here are the conventions: * We use the subset of C++11 supported by MSVC 2013 (ask if you think that something would be useful) * All new public functions in all classes need documenting comments on what they do and what behavior they follow, use doxy-comments formatted as `/** Description */`. Do not use asterisks on additional lines in multi-line comments. * Use spaces after the comment markers: `// Comment` instead of `//Comment`. A comment must be prefixed with two spaces if it's on the same line with code: - - `SomeFunction() // Note the two spaces prefixed to me and the space after the slashes.` - * All variable names and function names use CamelCase style. + - `SomeFunction()//Note the two spaces prefixed to me and the space after the slashes.` + * All variable names and function names use CamelCase style, with the exception of single letter variables. - `ThisIsAProperFunction()` `This_is_bad()` `this_is_bad` `GoodVariableName` `badVariableName`. * All member variables start with `m_`, all function parameters start with `a_`, all class names start with `c`. - `class cMonster { int m_Health; int DecreaseHealth(int a_Amount); }` -- cgit v1.2.3 From 1cef39cb73f5a9130d2cb9d497ca44350fb401d8 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 8 May 2015 23:20:22 +0100 Subject: Move chunk position accesses after the chunk validity checks --- src/Mobs/Monster.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 84f58ff85..9df5bd930 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -264,12 +264,14 @@ bool cMonster::EnsureProperDestination(cChunk & a_Chunk) cChunk * Chunk = a_Chunk.GetNeighborChunk(m_FinalDestination.x, m_FinalDestination.z); BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; - int RelX = m_FinalDestination.x - Chunk->GetPosX() * cChunkDef::Width; - int RelZ = m_FinalDestination.z - Chunk->GetPosZ() * cChunkDef::Width; + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } + + int RelX = m_FinalDestination.x - Chunk->GetPosX() * cChunkDef::Width; + int RelZ = m_FinalDestination.z - Chunk->GetPosZ() * cChunkDef::Width; // If destination in the air, go down to the lowest air block. while (m_FinalDestination.y > 0) -- cgit v1.2.3 From 218010cd96a3e887e7fbd8e18e1b74b7dc481036 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 8 May 2015 23:32:02 +0100 Subject: Fixed some Visual Studio warnings --- src/Bindings/LuaState.cpp | 18 +++++++++++++++--- src/Bindings/LuaState.h | 1 + src/Bindings/ManualBindings.cpp | 4 ++-- src/Broadcaster.cpp | 2 +- src/Chunk.cpp | 2 +- src/Mobs/Monster.cpp | 10 +++++----- src/Tracer.cpp | 6 +++--- src/Vector3.h | 20 ++++++++++---------- 8 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 9c1e2865c..fe47d45db 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -979,6 +979,18 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, float & a_ReturnedVal) +{ + if (lua_isnumber(m_LuaState, a_StackPos)) + { + a_ReturnedVal = static_cast(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal)); + } +} + + + + + void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal) { if (!lua_isnumber(m_LuaState, a_StackPos)) @@ -1415,7 +1427,7 @@ bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamEnd(int a_Param) { tolua_Error tolua_err; - if (tolua_isnoobj(m_LuaState, a_Param, &tolua_err)) + if (tolua_isnoobj(m_LuaState, a_Param, &tolua_err) == 1) { return true; } @@ -1437,7 +1449,7 @@ bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) ASSERT(IsValid()); tolua_Error tolua_err; - return tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err); + return (tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err) == 1); } @@ -1449,7 +1461,7 @@ bool cLuaState::IsParamNumber(int a_Param) ASSERT(IsValid()); tolua_Error tolua_err; - return tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err); + return (tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err) == 1); } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 3f2e828f3..4377ed5d0 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -251,6 +251,7 @@ public: void GetStackValue(int a_StackPos, bool & a_Value); void GetStackValue(int a_StackPos, cRef & a_Ref); void GetStackValue(int a_StackPos, double & a_Value); + void GetStackValue(int a_StackPos, float & a_ReturnedVal); void GetStackValue(int a_StackPos, eWeather & a_Value); void GetStackValue(int a_StackPos, int & a_Value); void GetStackValue(int a_StackPos, pBlockArea & a_Value); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20042a780..e87c02181 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2036,8 +2036,8 @@ static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S) // Read the params: cWorld * World = nullptr; AString Name; - double PosX, PosY, PosZ, OffX, OffY, OffZ; - double ParticleData; + float PosX, PosY, PosZ, OffX, OffY, OffZ; + float ParticleData; int ParticleAmmount; L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmmount); if (World == nullptr) diff --git a/src/Broadcaster.cpp b/src/Broadcaster.cpp index 7f2b65d09..594d12208 100644 --- a/src/Broadcaster.cpp +++ b/src/Broadcaster.cpp @@ -15,7 +15,7 @@ void cBroadcaster::BroadcastParticleEffect(const AString & a_ParticleName, const m_World->DoWithChunkAt(a_Src, [=](cChunk & a_Chunk) -> bool { - for (auto&& client : a_Chunk.GetAllClients()) + for (auto && client : a_Chunk.GetAllClients()) { if (client == a_Exclude) { diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 95dc7708e..bc8a2aff3 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1827,7 +1827,7 @@ bool cChunk::SetSignLines(int a_PosX, int a_PosY, int a_PosZ, const AString & a_ ) { MarkDirty(); - (reinterpret_cast(*itr))->SetLines(a_Line1, a_Line2, a_Line3, a_Line4); + reinterpret_cast(*itr)->SetLines(a_Line1, a_Line2, a_Line3, a_Line4); m_World->BroadcastBlockEntity(a_PosX, a_PosY, a_PosZ); return true; } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 84f58ff85..dc950ff7d 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -261,11 +261,11 @@ void cMonster::MoveToWayPoint(cChunk & a_Chunk) bool cMonster::EnsureProperDestination(cChunk & a_Chunk) { - cChunk * Chunk = a_Chunk.GetNeighborChunk(m_FinalDestination.x, m_FinalDestination.z); + cChunk * Chunk = a_Chunk.GetNeighborChunk(FloorC(m_FinalDestination.x), FloorC(m_FinalDestination.z)); BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; - int RelX = m_FinalDestination.x - Chunk->GetPosX() * cChunkDef::Width; - int RelZ = m_FinalDestination.z - Chunk->GetPosZ() * cChunkDef::Width; + int RelX = FloorC(m_FinalDestination.x) - Chunk->GetPosX() * cChunkDef::Width; + int RelZ = FloorC(m_FinalDestination.z) - Chunk->GetPosZ() * cChunkDef::Width; if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; @@ -274,7 +274,7 @@ bool cMonster::EnsureProperDestination(cChunk & a_Chunk) // If destination in the air, go down to the lowest air block. while (m_FinalDestination.y > 0) { - Chunk->GetBlockTypeMeta(RelX, m_FinalDestination.y - 1, RelZ, BlockType, BlockMeta); + Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y) - 1, RelZ, BlockType, BlockMeta); if (cBlockInfo::IsSolid(BlockType)) { break; @@ -288,7 +288,7 @@ bool cMonster::EnsureProperDestination(cChunk & a_Chunk) bool InWater = false; while (m_FinalDestination.y < cChunkDef::Height) { - Chunk->GetBlockTypeMeta(RelX, m_FinalDestination.y, RelZ, BlockType, BlockMeta); + Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y), RelZ, BlockType, BlockMeta); if (BlockType == E_BLOCK_STATIONARY_WATER) { InWater = true; diff --git a/src/Tracer.cpp b/src/Tracer.cpp index b6b0fd634..5fdaff15d 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -56,13 +56,13 @@ int cTracer::SigNum(float a_Num) { if (a_Num < 0.f) { - return -1.f; + return -1; } if (a_Num > 0.f) { - return 1.f; + return 1; } - return 0.f; + return 0; } diff --git a/src/Vector3.h b/src/Vector3.h index c5a3f9f05..089120cab 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -80,15 +80,15 @@ public: inline bool HasNonZeroLength(void) const { - #ifndef __GNUC__ - #pragma clang diagnostics push - #pragma clang diagnostics ignored "-Wfloat-equal" + #ifdef __clang__ + #pragma clang diagnostics push + #pragma clang diagnostics ignored "-Wfloat-equal" #endif return ((x != 0) || (y != 0) || (z != 0)); - #ifndef __GNUC__ - #pragma clang diagnostics pop + #ifdef __clang__ + #pragma clang diagnostics pop #endif } @@ -136,15 +136,15 @@ public: // Perform a strict comparison of the contents - we want to know whether this object is exactly equal // To perform EPS-based comparison, use the EqualsEps() function - #ifndef __GNUC__ - #pragma clang diagnostics push - #pragma clang diagnostics ignored "-Wfloat-equal" + #ifdef __clang__ + #pragma clang diagnostics push + #pragma clang diagnostics ignored "-Wfloat-equal" #endif return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); - #ifndef __GNUC__ - #pragma clang diagnostics pop + #ifdef __clang__ + #pragma clang diagnostics pop #endif } -- cgit v1.2.3 From eaba777a0e268cb883cabb3259989a1d2d9911f0 Mon Sep 17 00:00:00 2001 From: Woazboat Date: Sat, 9 May 2015 01:15:45 +0200 Subject: Fixed compiler warning overrides in Vector3.h --- src/Vector3.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index f116c07f6..355ba6a52 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -80,14 +80,14 @@ public: inline bool HasNonZeroLength(void) const { - #ifndef __GNUC__ + #ifdef __clang__ #pragma clang diagnostics push #pragma clang diagnostics ignored "-Wfloat-equal" #endif return ((x != 0) || (y != 0) || (z != 0)); - #ifndef __GNUC__ + #ifdef __clang__ #pragma clang diagnostics pop #endif } @@ -136,14 +136,14 @@ public: // Perform a strict comparison of the contents - we want to know whether this object is exactly equal // To perform EPS-based comparison, use the EqualsEps() function - #ifndef __GNUC__ + #ifdef __clang__ #pragma clang diagnostics push #pragma clang diagnostics ignored "-Wfloat-equal" #endif return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); - #ifndef __GNUC__ + #ifdef __clang__ #pragma clang diagnostics pop #endif } -- cgit v1.2.3 From 4642a50d627e5946079068c8aa19aa1e2b27846e Mon Sep 17 00:00:00 2001 From: Tristan Date: Fri, 8 May 2015 20:50:05 -0400 Subject: GetSizeName of cSlime and cMagmaCube is now static --- src/Mobs/MagmaCube.cpp | 2 +- src/Mobs/MagmaCube.h | 2 +- src/Mobs/Slime.cpp | 2 +- src/Mobs/Slime.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Mobs/MagmaCube.cpp b/src/Mobs/MagmaCube.cpp index e56cfa4b8..c5dd0def0 100644 --- a/src/Mobs/MagmaCube.cpp +++ b/src/Mobs/MagmaCube.cpp @@ -27,7 +27,7 @@ void cMagmaCube::GetDrops(cItems & a_Drops, cEntity * a_Killer) -const AString cMagmaCube::GetSizeName(int a_Size) const +AString cMagmaCube::GetSizeName(int a_Size) { if (a_Size > 1) { diff --git a/src/Mobs/MagmaCube.h b/src/Mobs/MagmaCube.h index d4b3997da..b914dc867 100644 --- a/src/Mobs/MagmaCube.h +++ b/src/Mobs/MagmaCube.h @@ -22,7 +22,7 @@ public: /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. Returns either "big" or "small". */ - const AString GetSizeName(int a_Size) const; + static AString GetSizeName(int a_Size); protected: diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index e42501e47..7fc4821d8 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -89,7 +89,7 @@ void cSlime::KilledBy(TakeDamageInfo & a_TDI) -const AString cSlime::GetSizeName(int a_Size) const +AString cSlime::GetSizeName(int a_Size) { if (a_Size > 1) { diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h index 29605992d..40131b101 100644 --- a/src/Mobs/Slime.h +++ b/src/Mobs/Slime.h @@ -27,7 +27,7 @@ public: /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. Returns either "big" or "small". */ - const AString GetSizeName(int a_Size) const; + static AString GetSizeName(int a_Size); protected: -- cgit v1.2.3 From 4dcd9a99245e6059d3f16723d1353efaa495ca08 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 9 May 2015 10:55:40 +0100 Subject: clang diagnostic not diagnostics fixed clang pragmas --- src/Vector3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index ed3f296a6..84e9183be 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -81,14 +81,14 @@ public: inline bool HasNonZeroLength(void) const { #ifdef __clang__ - #pragma clang diagnostics push - #pragma clang diagnostics ignored "-Wfloat-equal" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wfloat-equal" #endif return ((x != 0) || (y != 0) || (z != 0)); #ifdef __clang__ - #pragma clang diagnostics pop + #pragma clang diagnostic pop #endif } -- cgit v1.2.3 From e2e206d81bad6c8624fb81ef46a6c81a69792f15 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 9 May 2015 10:59:08 +0100 Subject: Fixed remaing pragmas --- src/Vector3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index 84e9183be..f051ce2d2 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -137,14 +137,14 @@ public: // To perform EPS-based comparison, use the EqualsEps() function #ifdef __clang__ - #pragma clang diagnostics push - #pragma clang diagnostics ignored "-Wfloat-equal" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wfloat-equal" #endif return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z)); #ifdef __clang__ - #pragma clang diagnostics pop + #pragma clang diagnostic pop #endif } -- cgit v1.2.3 From 61300ab9ef8b9eb16b0d334b1d406d429b7ea0c7 Mon Sep 17 00:00:00 2001 From: jammet Date: Sat, 9 May 2015 12:35:23 +0200 Subject: Rabbit and cooked rabbit now stackable And corrected the alphabetical ordering. --- src/Items/ItemHandler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 6bcb5f27a..7328456b4 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -543,8 +543,9 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_COMPASS: return 64; case E_ITEM_COOKED_CHICKEN: return 64; case E_ITEM_COOKED_FISH: return 64; - case E_ITEM_COOKED_PORKCHOP: return 64; case E_ITEM_COOKED_MUTTON: return 64; + case E_ITEM_COOKED_PORKCHOP: return 64; + case E_ITEM_COOKED_RABBIT: return 64; case E_ITEM_COOKIE: return 64; case E_ITEM_DARK_OAK_DOOR: return 64; case E_ITEM_DIAMOND: return 64; @@ -596,6 +597,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_RAW_FISH: return 64; case E_ITEM_RAW_MUTTON: return 64; case E_ITEM_RAW_PORKCHOP: return 64; + case E_ITEM_RAW_RABBIT: return 64; case E_ITEM_RED_APPLE: return 64; case E_ITEM_REDSTONE_DUST: return 64; case E_ITEM_REDSTONE_REPEATER: return 64; -- cgit v1.2.3 From c13b1931ff26a5643c9fe68ab32b1e362cfacd70 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 9 May 2015 09:25:09 +0200 Subject: More style checking. Spaces around some operators are checked. --- src/Bindings/LuaState.cpp | 4 +- src/Bindings/PluginLua.h | 2 +- src/BlockEntities/MobHeadEntity.cpp | 2 +- src/BlockEntities/MobHeadEntity.h | 2 +- src/Blocks/BlockComparator.h | 2 +- src/Blocks/BlockDoor.cpp | 6 +-- src/Blocks/BlockFire.h | 6 +-- src/Blocks/BlockLever.h | 2 +- src/Blocks/BlockPiston.h | 2 +- src/Blocks/BlockRail.h | 16 +++---- src/Blocks/BlockTrapdoor.h | 2 +- src/BoundingBox.h | 4 +- src/CheckBasicStyle.lua | 21 ++++++++++ src/Chunk.cpp | 6 +-- src/ClientHandle.cpp | 12 +++--- src/ClientHandle.h | 4 +- src/Defines.h | 2 +- src/Enchantments.h | 2 +- src/Entities/Entity.cpp | 7 ++-- src/Entities/Entity.h | 4 +- src/Entities/EntityEffect.cpp | 4 +- src/Entities/Minecart.cpp | 4 +- src/Entities/Minecart.h | 5 +-- src/Entities/Player.cpp | 12 +++--- src/Entities/Player.h | 2 +- src/Entities/ProjectileEntity.h | 2 +- src/Generating/Caves.cpp | 4 +- src/Generating/ChunkGenerator.cpp | 4 +- src/Generating/FinishGen.cpp | 2 +- src/Generating/HeiGen.cpp | 2 +- src/Generating/IntGen.h | 4 +- src/Generating/Noise3DGenerator.cpp | 2 +- src/Generating/ProtIntGen.h | 2 +- src/Generating/RainbowRoadsGen.cpp | 2 +- src/Generating/RainbowRoadsGen.h | 2 +- src/Generating/Ravines.cpp | 4 +- src/Generating/StructGen.cpp | 2 +- src/Generating/TestRailsGen.cpp | 2 +- src/Generating/TestRailsGen.h | 4 +- src/Generating/Trees.cpp | 4 +- src/Generating/UnderwaterBaseGen.cpp | 2 +- src/Generating/UnderwaterBaseGen.h | 2 +- src/Generating/VillageGen.cpp | 2 +- src/Generating/VillageGen.h | 2 +- src/Globals.h | 4 +- src/HTTPServer/EnvelopeParser.h | 2 +- src/HTTPServer/HTTPMessage.cpp | 2 +- src/IniFile.cpp | 4 +- src/IniFile.h | 10 ++--- src/Items/ItemLighter.h | 2 +- src/Items/ItemLilypad.h | 2 +- src/Map.h | 2 +- src/MobCensus.cpp | 4 +- src/Mobs/Monster.h | 2 +- src/Mobs/Path.h | 2 +- src/Noise/Noise.cpp | 58 +++++++++++++------------- src/OSSupport/CriticalSection.h | 2 +- src/OSSupport/File.h | 2 +- src/OSSupport/Network.h | 2 +- src/Protocol/MojangAPI.cpp | 4 +- src/Protocol/Protocol17x.cpp | 4 +- src/Protocol/Protocol18x.cpp | 4 +- src/RankManager.cpp | 2 +- src/Simulator/FloodyFluidSimulator.h | 2 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 10 ++--- src/UI/DropSpenserWindow.cpp | 2 +- src/UI/DropSpenserWindow.h | 2 +- src/UI/FurnaceWindow.cpp | 2 +- src/UI/SlotArea.h | 2 +- src/VoronoiMap.h | 2 +- src/World.cpp | 4 +- src/World.h | 6 +-- src/WorldStorage/FastNBT.h | 2 +- src/WorldStorage/MapSerializer.cpp | 8 ++-- src/WorldStorage/ScoreboardSerializer.cpp | 2 +- src/WorldStorage/StatSerializer.cpp | 2 +- src/WorldStorage/WSSAnvil.cpp | 8 ++-- src/XMLParser.h | 40 +++++++++--------- 78 files changed, 207 insertions(+), 186 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 9c1e2865c..28bf87091 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -19,13 +19,13 @@ extern "C" #include "../Entities/Entity.h" #include "../BlockEntities/BlockEntity.h" -// fwd: SQLite/lsqlite3.c +// fwd: "SQLite/lsqlite3.c" extern "C" { int luaopen_lsqlite3(lua_State * L); } -// fwd: LuaExpat/lxplib.c: +// fwd: "LuaExpat/lxplib.c": extern "C" { int luaopen_lxp(lua_State * L); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 393737b34..bedb3d83b 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -20,7 +20,7 @@ -// fwd: UI/Window.h +// fwd: "UI/Window.h" class cWindow; diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp index 67e13ffb2..328ade23a 100644 --- a/src/BlockEntities/MobHeadEntity.cpp +++ b/src/BlockEntities/MobHeadEntity.cpp @@ -1,7 +1,7 @@ // MobHeadEntity.cpp -// Implements the cMobHeadEntity class representing a single skull/head in the world +// Implements the cMobHeadEntity class representing a single skull / head in the world #include "Globals.h" #include "MobHeadEntity.h" diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 7f08c5ab2..b6760b40a 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -1,6 +1,6 @@ // MobHeadEntity.h -// Declares the cMobHeadEntity class representing a single skull/head in the world +// Declares the cMobHeadEntity class representing a single skull / head in the world diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index 3443fc69e..ed73a162e 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -22,7 +22,7 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR + Meta ^= 0x04; // Toggle 3rd (addition / subtraction) bit with XOR a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index d2bf180be..d13c8d657 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -134,7 +134,7 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) return a_Meta; } - // Holds open/closed meta data. 0x0C == 1100. + // Holds open / closed meta data. 0x0C == 1100. NIBBLETYPE OtherMeta = a_Meta & 0x0C; // Mirrors according to a table. 0x03 == 0011. @@ -152,7 +152,7 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) { - // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data + // Top bit (0x08) contains door panel type (Top / Bottom panel) Only Bottom panels contain position data // Return a_Meta if panel is a top panel (0x08 bit is set to 1) // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored @@ -165,7 +165,7 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) return a_Meta; } - // Holds open/closed meta data. 0x0C == 1100. + // Holds open / closed meta data. 0x0C == 1100. NIBBLETYPE OtherMeta = a_Meta & 0x0C; // Mirrors according to a table. 0x03 == 0011. diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index bafd385ab..2038df94b 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -106,7 +106,7 @@ public: void FindAndSetPortalFrame(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface) { int MaxY = FindObsidianCeiling(X, Y, Z, a_ChunkInterface); // Get topmost obsidian block as reference for all other checks - int X1 = X + 1, Z1 = Z + 1, X2 = X - 1, Z2 = Z - 1; // Duplicate XZ values, add/subtract one as we've checked the original already the line above + int X1 = X + 1, Z1 = Z + 1, X2 = X - 1, Z2 = Z - 1; // Duplicate XZ values, add / subtract one as we've checked the original already the line above if (MaxY == 0) // Oh noes! Not a portal coordinate :( { @@ -139,7 +139,7 @@ public: return; } - /** Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable + /** Evaluates if coordinates are a portal going XP / XM; returns true if so, and writes boundaries to variable Takes coordinates of base block and Y coord of target obsidian ceiling */ bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface) { @@ -179,7 +179,7 @@ public: return (FoundFrameXP && FoundFrameXM); } - /// Evaluates if coords are a portal going ZP/ZM; returns true if so, and writes boundaries to variable + /// Evaluates if coords are a portal going ZP / ZM; returns true if so, and writes boundaries to variable bool FindPortalSliceZ(int X, int Y, int Z1, int Z2, int MaxY, cChunkInterface & a_ChunkInterface) { Dir = 2; diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index f5bedea6c..2da138e5f 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -19,7 +19,7 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { - // Flip the ON bit on/off using the XOR bitwise operation + // Flip the ON bit on / off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 9a891025a..5933d4885 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -108,7 +108,7 @@ private: case E_BLOCK_ENCHANTMENT_TABLE: case E_BLOCK_END_PORTAL: case E_BLOCK_END_PORTAL_FRAME: - // Notice the lack of an E_BLOCK_ENDER_CHEST here; its because ender chests can totally be pushed/pulled in MCS :) + // Notice the lack of an E_BLOCK_ENDER_CHEST here; its because ender chests can totally be pushed / pulled in MCS :) case E_BLOCK_FURNACE: case E_BLOCK_LIT_FURNACE: case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 02fe3aa95..a2e27a351 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -502,11 +502,11 @@ public: // Save powered rail flag. NIBBLETYPE OtherMeta = a_Meta & 0x08; // Rotates according to table; 0x07 == 0111. - // Rails can either be flat (North/South) or Ascending (Asc. East) + // Rails can either be flat (North / South) or Ascending (Asc. East) switch (a_Meta & 0x07) { - case 0x00: return 0x01 + OtherMeta; // North/South -> East/West - case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + case 0x00: return 0x01 + OtherMeta; // North / South -> East / West + case 0x01: return 0x00 + OtherMeta; // East / West -> North / South case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West @@ -538,11 +538,11 @@ public: // Save powered rail flag. NIBBLETYPE OtherMeta = a_Meta & 0x08; // Rotates according to table; 0x07 == 0111. - // Rails can either be flat (North/South) or Ascending (Asc. East) + // Rails can either be flat (North / South) or Ascending (Asc. East) switch (a_Meta & 0x07) { - case 0x00: return 0x01 + OtherMeta; // North/South -> East/West - case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + case 0x00: return 0x01 + OtherMeta; // North / South -> East / West + case 0x01: return 0x00 + OtherMeta; // East / West -> North / South case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West @@ -574,7 +574,7 @@ public: // Save powered rail flag. NIBBLETYPE OtherMeta = a_Meta & 0x08; // Mirrors according to table; 0x07 == 0111. - // Rails can either be flat (North/South) or Ascending (Asc. East) + // Rails can either be flat (North / South) or Ascending (Asc. East) switch (a_Meta & 0x07) { case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North @@ -605,7 +605,7 @@ public: // Save powered rail flag. NIBBLETYPE OtherMeta = a_Meta & 0x08; // Mirrors according to table; 0x07 == 0111. - // Rails can either be flat (North/South) or Ascending (Asc. East) + // Rails can either be flat (North / South) or Ascending (Asc. East) switch (a_Meta & 0x07) { case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 8c96de0f1..dbb0b5a5b 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -35,7 +35,7 @@ public: return; } - // Flip the ON bit on/off using the XOR bitwise operation + // Flip the ON bit on / off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); diff --git a/src/BoundingBox.h b/src/BoundingBox.h index 928e62afa..8ea758ac7 100644 --- a/src/BoundingBox.h +++ b/src/BoundingBox.h @@ -57,10 +57,10 @@ public: /// Returns true if a boundingbox specified by a_Min and a_Max is inside this bounding box bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max); - /// Returns true if the specified point is inside the bounding box specified by its min/max corners + /// Returns true if the specified point is inside the bounding box specified by its min / max corners static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point); - /// Returns true if the specified point is inside the bounding box specified by its min/max corners + /// Returns true if the specified point is inside the bounding box specified by its min / max corners static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z); /** Returns true if this bounding box is intersected by the line specified by its two points diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 8cd454e8f..09e64b954 100755 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -149,6 +149,27 @@ local g_ViolationPatterns = -- No space before a closing parenthesis: {" %)", "Remove the space before \")\""}, + + -- Check spaces around "+": + {"^[a-zA-Z0-9]+%+[a-zA-Z0-9]+", "Add space around +"}, + {"[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%+[a-zA-Z0-9]+", "Add space around +"}, + --[[ + -- Cannot check these because of text such as "X+" and "+2" appearing in some comments. + {"^[a-zA-Z0-9]+ %+[a-zA-Z0-9]+", "Add space after +"}, + {"[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+ %+[a-zA-Z0-9]+", "Add space after +"}, + {"^[a-zA-Z0-9]+%+ [a-zA-Z0-9]+", "Add space before +"}, + {"[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%+ [a-zA-Z0-9]+", "Add space before +"}, + --]] + + -- Cannot check spaces around "-", because the minus is sometimes used as a hyphen between-words + + -- Check spaces around "*": + {"^[a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, + + -- Check spaces around "/": + {"^[a-zA-Z0-9]+%/[a-zA-Z0-9]+", "Add space around /"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%/[a-zA-Z0-9]+", "Add space around /"}, } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 95dc7708e..bed5aa991 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -737,7 +737,7 @@ void cChunk::ProcessQueuedSetBlocks(void) { if (GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ) == itr->m_PreviousType) { - // Current world age is bigger than/equal to target world age - delay time reached AND + // Current world age is bigger than / equal to target world age - delay time reached AND // Previous block type was the same as current block type (to prevent duplication) SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); // SetMeta doesn't send to client itr = m_SetBlockQueue.erase(itr); @@ -751,7 +751,7 @@ void cChunk::ProcessQueuedSetBlocks(void) } else { - // Current world age is bigger than/equal to target world age - delay time reached + // Current world age is bigger than / equal to target world age - delay time reached SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); itr = m_SetBlockQueue.erase(itr); LOGD("Successfully set queued block - previous type ignored"); @@ -1026,7 +1026,7 @@ void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl case E_BLOCK_FARMLAND: { // DEBUG: This is here to catch FS #349 - melons growing over other crops. - LOG("Growing melon/pumpkin overwriting %s, growing on %s", + LOG("Growing melon / pumpkin overwriting %s, growing on %s", ItemTypeToString(BlockType[CheckType]).c_str(), ItemTypeToString(Soil).c_str() ); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b12ab419b..7117229f7 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -436,7 +436,7 @@ bool cClientHandle::StreamNextChunk(void) { Vector3d Vector = Position + LookVector * cChunkDef::Width * Range; - // Get the chunk from the x/z coords. + // Get the chunk from the x / z coords. int RangeX, RangeZ = 0; cChunkDef::BlockToChunk(FloorC(Vector.x), FloorC(Vector.z), RangeX, RangeZ); @@ -454,7 +454,7 @@ bool cClientHandle::StreamNextChunk(void) continue; } - // If the chunk already loading/loaded -> skip + // If the chunk already loading / loaded -> skip if ( (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), Coords) != m_ChunksToSend.end()) || (std::find(m_LoadedChunks.begin(), m_LoadedChunks.end(), Coords) != m_LoadedChunks.end()) @@ -492,7 +492,7 @@ bool cClientHandle::StreamNextChunk(void) { cChunkCoords Coords = *itr; - // If the chunk already loading/loaded -> skip + // If the chunk already loading / loaded -> skip if ( (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), Coords) != m_ChunksToSend.end()) || (std::find(m_LoadedChunks.begin(), m_LoadedChunks.end(), Coords) != m_LoadedChunks.end()) @@ -1154,7 +1154,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc return; } - // Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client: + // Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig / aim bug in the client: m_HasStartedDigging = true; m_LastDigBlockX = a_BlockX; m_LastDigBlockY = a_BlockY; @@ -1201,7 +1201,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo (m_LastDigBlockZ != a_BlockZ) ) { - LOGD("Prevented a dig/aim bug in the client (finish {%d, %d, %d} vs start {%d, %d, %d}, HSD: %s)", + LOGD("Prevented a dig / aim bug in the client (finish {%d, %d, %d} vs start {%d, %d, %d}, HSD: %s)", a_BlockX, a_BlockY, a_BlockZ, m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ, (m_HasStartedDigging ? "True" : "False") @@ -1359,7 +1359,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (!CheckBlockInteractionsRate()) { - Kick("Too many blocks were placed/interacted with per unit time - hacked client?"); + Kick("Too many blocks were placed / interacted with per unit time - hacked client?"); return; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7992d6bc2..61f29b57c 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -391,7 +391,7 @@ private: cPlayer * m_Player; - bool m_HasSentDC; ///< True if a D/C packet has been sent in either direction + bool m_HasSentDC; ///< True if a Disconnect packet has been sent in either direction // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk int m_LastStreamedChunkX; @@ -416,7 +416,7 @@ private: int m_BlockDigAnimY; int m_BlockDigAnimZ; - // To avoid dig/aim bug in the client, store the last position given in a DIG_START packet and compare to that when processing the DIG_FINISH packet: + // To avoid dig / aim bug in the client, store the last position given in a DIG_START packet and compare to that when processing the DIG_FINISH packet: bool m_HasStartedDigging; int m_LastDigBlockX; int m_LastDigBlockY; diff --git a/src/Defines.h b/src/Defines.h index c2f46c241..787eacab8 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -229,7 +229,7 @@ inline const char * ClickActionToString(eClickAction a_ClickAction) -/** Returns a blockface mirrored around the Y axis (doesn't change up/down). */ +/** Returns a blockface mirrored around the Y axis (doesn't change up / down). */ inline eBlockFace MirrorBlockFaceY(eBlockFace a_BlockFace) { switch (a_BlockFace) diff --git a/src/Enchantments.h b/src/Enchantments.h index e8e84d43c..9c1c54ae9 100644 --- a/src/Enchantments.h +++ b/src/Enchantments.h @@ -14,7 +14,7 @@ -// fwd: WorldStorage/FastNBT.h +// fwd: "WorldStorage/FastNBT.h" class cFastNBTWriter; class cParsedNBT; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index b87cf51a6..4a909a1fd 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1309,7 +1309,8 @@ bool cEntity::DetectPortal() if (IsPlayer()) { - ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); // Send a respawn packet before world is loaded/generated so the client isn't left in limbo + // Send a respawn packet before world is loaded / generated so the client isn't left in limbo + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); } return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); @@ -1688,8 +1689,8 @@ void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude) { m_World->BroadcastEntityRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ, a_Exclude); } - // Clients seem to store two positions, one for the velocity packet and one for the teleport/relmove packet - // The latter is only changed with a relmove/teleport, and m_LastPos stores this position + // Clients seem to store two positions, one for the velocity packet and one for the teleport / relmove packet + // The latter is only changed with a relmove / teleport, and m_LastPos stores this position m_LastPos = GetPosition(); } else diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index dd6190ced..fecbb9bf5 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -474,7 +474,7 @@ protected: static cCriticalSection m_CSCount; static UInt32 m_EntityCount; - /** Measured in meter/second (m/s) */ + /** Measured in meters / second (m / s) */ Vector3d m_Speed; /** The ID of the entity that is guaranteed to be unique within a single run of the server. @@ -494,7 +494,7 @@ protected: /** Stores whether head yaw has been set manually */ bool m_bDirtyHead; - /** Stores whether our yaw/pitch/roll (body orientation) has been set manually */ + /** Stores whether our yaw / pitch / roll (body orientation) has been set manually */ bool m_bDirtyOrientation; /** Stores whether we have sent a Velocity packet with a speed of zero (no speed) to the client diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index bae686b77..c8be414d4 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -102,11 +102,11 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) // If potion is level II, half the duration. If not, stays the same TierCoeff = (GetPotionEffectIntensity(a_ItemDamage) > 0) ? 0.5 : 1; - // If potion is extended, multiply duration by 8/3. If not, stays the same + // If potion is extended, multiply duration by 8 / 3. If not, stays the same // Extended potion if sixth lowest bit is set ExtCoeff = (a_ItemDamage & 0x40) ? (8.0 / 3.0) : 1; - // If potion is splash potion, multiply duration by 3/4. If not, stays the same + // If potion is splash potion, multiply duration by 3 / 4. If not, stays the same SplashCoeff = IsPotionDrinkable(a_ItemDamage) ? 1 : 0.75; // Ref.: diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 3d56570ba..b80759d24 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -905,7 +905,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } /* Check to which side the minecart is to be pushed. - Let's consider a z-x-coordinate system where the minecart is the center (0/0). + Let's consider a z-x-coordinate system where the minecart is the center (0, 0). The minecart moves along the line x = -z, the perpendicular line to this is x = z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( @@ -954,7 +954,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } /* Check to which side the minecart is to be pushed. - Let's consider a z-x-coordinate system where the minecart is the center (0/0). + Let's consider a z-x-coordinate system where the minecart is the center (0, 0). The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 898776e71..d1736e9b9 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -29,7 +29,7 @@ public: enum ePayload { mpNone = 0, // Empty minecart, ridable by player or mobs - mpChest = 1, // Minecart-with-chest, can store a grid of 3*8 items + mpChest = 1, // Minecart-with-chest, can store a grid of 3 * 8 items mpFurnace = 2, // Minecart-with-furnace, can be powered mpTNT = 3, // Minecart-with-TNT, can be blown up with activator rail mpHopper = 5, // Minecart-with-hopper, can be hopper @@ -54,8 +54,7 @@ protected: cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z); /** Handles physics on normal rails - For each tick, slow down on flat rails, speed up or slow down on ascending/descending rails (depending on direction), and turn on curved rails - */ + For each tick, slow down on flat rails, speed up or slow down on ascending / descending rails (depending on direction), and turn on curved rails. */ void HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt); /** Handles powered rail physics diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 7f625f5d4..607a663de 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -355,7 +355,7 @@ float cPlayer::GetXpPercentage() int currentLevel_XpBase = XpForLevel(currentLevel); return static_cast(m_CurrentXp - currentLevel_XpBase) / - static_cast(XpForLevel(1+currentLevel) - currentLevel_XpBase); + static_cast(XpForLevel(1 + currentLevel) - currentLevel_XpBase); } @@ -364,7 +364,7 @@ float cPlayer::GetXpPercentage() bool cPlayer::SetCurrentExperience(int a_CurrentXp) { - if (!(a_CurrentXp >= 0) || (a_CurrentXp > (std::numeric_limits().max() - m_LifetimeTotalXp))) + if (!(a_CurrentXp >= 0) || (a_CurrentXp > (std::numeric_limits::max() - m_LifetimeTotalXp))) { LOGWARNING("Tried to update experiece with an invalid Xp value: %d", a_CurrentXp); return false; // oops, they gave us a dodgey number @@ -403,7 +403,7 @@ int cPlayer::DeltaExperience(int a_Xp_delta) m_LifetimeTotalXp += a_Xp_delta; } - LOGD("Player \"%s\" gained/lost %d experience, total is now: %d", GetName().c_str(), a_Xp_delta, m_CurrentXp); + LOGD("Player \"%s\" gained / lost %d experience, total is now: %d", GetName().c_str(), a_Xp_delta, m_CurrentXp); // Set experience to be updated m_bDirtyExperience = true; @@ -1771,7 +1771,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt(); // Load the player stats. - // We use the default world name (like bukkit) because stats are shared between dimensions/worlds. + // We use the default world name (like bukkit) because stats are shared between dimensions / worlds. cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats); StatSerializer.Load(); @@ -1868,7 +1868,7 @@ bool cPlayer::SaveToDisk() } // Save the player stats. - // We use the default world name (like bukkit) because stats are shared between dimensions/worlds. + // We use the default world name (like bukkit) because stats are shared between dimensions / worlds. cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats); if (!StatSerializer.Save()) { @@ -2076,7 +2076,7 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) } else { - if (Value >= 25) // Ignore small/slow movement + if (Value >= 25) // Ignore small / slow movement { m_Stats.AddValue(statDistFlown, Value); } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 4b8c01dc4..a0cd9b1d6 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -644,7 +644,7 @@ protected: virtual void Destroyed(void); - /** Filters out damage for creative mode/friendly fire */ + /** Filters out damage for creative mode / friendly fire */ virtual bool DoTakeDamage(TakeDamageInfo & TDI) override; /** Stops players from burning in creative mode */ diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index de460a8ad..7ee87f93a 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -109,7 +109,7 @@ protected: eKind m_ProjectileKind; /** The structure for containing the entity ID and name who has created this projectile - The ID and/or name may be nullptr (e.g. for dispensers/mobs). */ + The ID and / or name may be nullptr (e.g. for dispensers / mobs). */ CreatorData m_CreatorData; /** True if the projectile has hit the ground and is stuck there */ diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 1e8dbef90..0a9b170fa 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -237,7 +237,7 @@ bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints & return true; } - // Smoothing: for each line segment, add points on its 1/4 lengths + // Smoothing: for each line segment, add points on its 1 / 4 lengths bool res = false; size_t Num = a_Src.size() - 2; // this many intermediary points a_Dst.clear(); @@ -488,7 +488,7 @@ void cCaveTunnel::ProcessChunk( continue; } - // Carve out a sphere around the xyz point, m_Radius in diameter; skip 3/7 off the top and bottom: + // Carve out a sphere around the xyz point, m_Radius in diameter; skip 3 / 7 off the top and bottom: int DifX = itr->m_BlockX - BlockStartX; // substitution for faster calc int DifY = itr->m_BlockY; int DifZ = itr->m_BlockZ - BlockStartZ; // substitution for faster calc diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 854aac60d..72d8f5258 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -209,7 +209,7 @@ void cChunkGenerator::Execute(void) { if ((NumChunksGenerated > 16) && (clock() - LastReportTick > CLOCKS_PER_SEC)) { - LOG("Chunk generator performance: %.2f ch/s (%d ch total)", + LOG("Chunk generator performance: %.2f ch / sec (%d ch total)", (double)NumChunksGenerated * CLOCKS_PER_SEC/ (clock() - GenerationStart), NumChunksGenerated ); @@ -241,7 +241,7 @@ void cChunkGenerator::Execute(void) // Display perf info once in a while: if ((NumChunksGenerated > 16) && (clock() - LastReportTick > 2 * CLOCKS_PER_SEC)) { - LOG("Chunk generator performance: %.2f ch/s (%d ch total)", + LOG("Chunk generator performance: %.2f ch / sec (%d ch total)", (double)NumChunksGenerated * CLOCKS_PER_SEC / (clock() - GenerationStart), NumChunksGenerated ); diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 7541c8598..00b34bddd 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -195,7 +195,7 @@ void cFinishGenGlowStone::GenFinish(cChunkDesc & a_ChunkDesc) // The maximum size for a string of glowstone can get 3 - 5 blocks long int Size = 3 + m_Noise.IntNoise3DInt(ChunkX, i, ChunkZ) % 3; - // Generate X/Z coordinates. + // Generate X / Z coordinates. int X = Size + (m_Noise.IntNoise2DInt(i, Size) % (cChunkDef::Width - Size * 2)); int Z = Size + (m_Noise.IntNoise2DInt(X, i) % (cChunkDef::Width - Size * 2)); diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 54567cb4d..e34ffc57c 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -667,7 +667,7 @@ public: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) { - // Generate the biomes for the 3*3 neighbors: + // Generate the biomes for the 3 * 3 neighbors: cChunkDef::BiomeMap neighborBiomes[3][3]; for (int z = 0; z < 3; z++) for (int x = 0; x < 3; x++) { diff --git a/src/Generating/IntGen.h b/src/Generating/IntGen.h index 854563f41..9cc881639 100644 --- a/src/Generating/IntGen.h +++ b/src/Generating/IntGen.h @@ -5,7 +5,7 @@ /* The integers generated may be interpreted in several ways: -- land/see designators +- land / sea designators - 0 = ocean - >0 = land - biome group @@ -310,7 +310,7 @@ public: } } - // Copy from Cache into a_Values; take into account the even/odd offsets in a_Min: + // Copy from Cache into a_Values; take into account the even / odd offsets in a_Min: for (int z = 0; z < SizeZ; ++z) { memcpy(a_Values + z * SizeX, cache + (z + (a_MinZ & 1)) * lowStepX + (a_MinX & 1), SizeX * sizeof(int)); diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index eadc66a4e..63e88c2a8 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -680,7 +680,7 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch void cBiomalNoise3DComposable::CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint) { - // Generate the 3*3 chunks of biomes around this chunk: + // Generate the 3 * 3 chunks of biomes around this chunk: cChunkDef::BiomeMap neighborBiomes[3 * 3]; for (int z = 0; z < 3; z++) { diff --git a/src/Generating/ProtIntGen.h b/src/Generating/ProtIntGen.h index e709222fe..9e471e8bb 100644 --- a/src/Generating/ProtIntGen.h +++ b/src/Generating/ProtIntGen.h @@ -229,7 +229,7 @@ public: } } - // Copy from Cache into a_Values; take into account the even/odd offsets in a_Min: + // Copy from Cache into a_Values; take into account the even / odd offsets in a_Min: for (int z = 0; z < a_SizeZ; ++z) { memcpy(a_Values + z * a_SizeX, cache + (z + (a_MinZ & 1)) * lowStepX + (a_MinX & 1), a_SizeX * sizeof(int)); diff --git a/src/Generating/RainbowRoadsGen.cpp b/src/Generating/RainbowRoadsGen.cpp index c3c07cdec..fd4a81692 100644 --- a/src/Generating/RainbowRoadsGen.cpp +++ b/src/Generating/RainbowRoadsGen.cpp @@ -61,7 +61,7 @@ protected: /** The noise used as a pseudo-random generator */ cNoise m_Noise; - /** Maximum size, in X/Z blocks, of the village (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; /** Borders of the vilalge - no item may reach out of this cuboid. */ diff --git a/src/Generating/RainbowRoadsGen.h b/src/Generating/RainbowRoadsGen.h index 5813e1d14..52d48ceca 100644 --- a/src/Generating/RainbowRoadsGen.h +++ b/src/Generating/RainbowRoadsGen.h @@ -34,7 +34,7 @@ protected: /** Maximum depth of the generator tree*/ int m_MaxDepth; - /** Maximum size, in X/Z blocks, of the base (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the structure (radius from the origin) */ int m_MaxSize; diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp index 70b9d0b62..9f8f69139 100644 --- a/src/Generating/Ravines.cpp +++ b/src/Generating/Ravines.cpp @@ -124,7 +124,7 @@ cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise) { - // Modify the size slightly to have different-sized ravines (1/2 to 1/1 of a_Size): + // Modify the size slightly to have different-sized ravines (1 / 2 to 1 / 1 of a_Size): a_Size = (512 + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 11 * a_BlockZ, a_BlockX + a_BlockZ) / 17) % 512)) * a_Size / 1024; // The complete offset of the ravine from its cellpoint, up to 2 * a_Size in each direction @@ -177,7 +177,7 @@ void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cR return; } - // Smoothing: for each line segment, add points on its 1/4 lengths + // Smoothing: for each line segment, add points on its 1 / 4 lengths size_t Num = a_Src.size() - 2; // this many intermediary points a_Dst.clear(); a_Dst.reserve(Num * 2 + 2); diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 2d5a73739..7572cdcbf 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -311,7 +311,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore rnd /= cChunkDef::Width; int BaseY = rnd % a_MaxHeight; rnd /= a_MaxHeight; - int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger + int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1 / 4 larger int Num = 0; while (Num < NestSize) { diff --git a/src/Generating/TestRailsGen.cpp b/src/Generating/TestRailsGen.cpp index 66ab8b33f..8256b55a0 100644 --- a/src/Generating/TestRailsGen.cpp +++ b/src/Generating/TestRailsGen.cpp @@ -61,7 +61,7 @@ protected: /** The noise used as a pseudo-random generator */ cNoise m_Noise; - /** Maximum size, in X/Z blocks, of the structure (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the structure (radius from the origin) */ int m_MaxSize; /** Borders of the structure - no item may reach out of this cuboid. */ diff --git a/src/Generating/TestRailsGen.h b/src/Generating/TestRailsGen.h index 5b0ce95f4..88e38b368 100644 --- a/src/Generating/TestRailsGen.h +++ b/src/Generating/TestRailsGen.h @@ -31,10 +31,10 @@ protected: /** The noise used for generating random numbers */ cNoise m_Noise; - /** Maximum depth of the generator tree*/ + /** Maximum depth of the generator tree */ int m_MaxDepth; - /** Maximum size, in X/Z blocks, of the base (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the structure (radius from the origin) */ int m_MaxSize; diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 9e72a688f..72fe5f819 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -499,7 +499,7 @@ void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - // Third and fourth layers - BigO2 and maybe 2*Corners: + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); @@ -673,7 +673,7 @@ void GetTallBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_ PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - // Third and fourth layers - BigO2 and maybe 2*Corners: + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); diff --git a/src/Generating/UnderwaterBaseGen.cpp b/src/Generating/UnderwaterBaseGen.cpp index 8916f4b5f..dbc4aef1b 100644 --- a/src/Generating/UnderwaterBaseGen.cpp +++ b/src/Generating/UnderwaterBaseGen.cpp @@ -61,7 +61,7 @@ protected: /** The noise used as a pseudo-random generator */ cNoise m_Noise; - /** Maximum size, in X/Z blocks, of the village (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the base (radius from the origin) */ int m_MaxSize; /** Borders of the vilalge - no item may reach out of this cuboid. */ diff --git a/src/Generating/UnderwaterBaseGen.h b/src/Generating/UnderwaterBaseGen.h index b24eb1075..9433a1905 100644 --- a/src/Generating/UnderwaterBaseGen.h +++ b/src/Generating/UnderwaterBaseGen.h @@ -34,7 +34,7 @@ protected: /** Maximum depth of the generator tree*/ int m_MaxDepth; - /** Maximum size, in X/Z blocks, of the base (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the structure (radius from the origin) */ int m_MaxSize; /** The underlying biome generator that defines whether the base is created or not */ diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index f7d9a8316..a3f8caa46 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -162,7 +162,7 @@ protected: /** The noise used as a pseudo-random generator */ cNoise m_Noise; - /** Maximum size, in X/Z blocks, of the village (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; /** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */ diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index ed8d739df..c384ed9e5 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -32,7 +32,7 @@ protected: /** Maximum depth of the generator tree*/ int m_MaxDepth; - /** Maximum size, in X/Z blocks, of the village (radius from the origin) */ + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; /** Minimum density - percentage of allowed house connections. Range [0, 100] */ diff --git a/src/Globals.h b/src/Globals.h index bd180c08f..1f354ae77 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -18,9 +18,9 @@ // Useful warnings from warning level 4: #pragma warning(3 : 4189) // Local variable is initialized but not referenced - #pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch + #pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed / unsigned mismatch #pragma warning(3 : 4310) // Cast truncates constant value - #pragma warning(3 : 4389) // Signed/unsigned mismatch + #pragma warning(3 : 4389) // Signed / unsigned mismatch #pragma warning(3 : 4505) // Unreferenced local function has been removed #pragma warning(3 : 4701) // Potentially unitialized local variable used #pragma warning(3 : 4702) // Unreachable code diff --git a/src/HTTPServer/EnvelopeParser.h b/src/HTTPServer/EnvelopeParser.h index e96d80abe..fe226d1f8 100644 --- a/src/HTTPServer/EnvelopeParser.h +++ b/src/HTTPServer/EnvelopeParser.h @@ -61,7 +61,7 @@ public: AString m_LastValue; - /** Notifies the callback of the key/value stored in m_LastKey/m_LastValue, then erases them */ + /** Notifies the callback of the key / value stored in m_LastKey / m_LastValue, then erases them */ void NotifyLast(void); /** Parses one line of header data. Returns true if successful */ diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp index c87b3cc8b..6762a22f8 100644 --- a/src/HTTPServer/HTTPMessage.cpp +++ b/src/HTTPServer/HTTPMessage.cpp @@ -202,7 +202,7 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size) m_IsValid = false; return AString::npos; } - // Check that there's HTTP/version at the end + // Check that there's HTTP / version at the end if (strncmp(m_IncomingHeaderData.c_str() + URLEnd + 1, "HTTP/1.", 7) != 0) { m_IsValid = false; diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 3a213a90e..99c0a5f0f 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -1,11 +1,11 @@ // IniFile.cpp: Implementation of the CIniFile class. // Written by: Adam Clauss // Email: cabadam@houston.rr.com -// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// You may use this class / code as you wish in your programs. Feel free to distribute it, and // email suggested changes to me. // // Rewritten by: Shane Hill -// Date: 21/08/2001 +// Date: 2001-08-21 // Email: Shane.Hill@dsto.defence.gov.au // Reason: Remove dependancy on MFC. Code should compile on any // platform. diff --git a/src/IniFile.h b/src/IniFile.h index 3e717723f..71fea3a00 100644 --- a/src/IniFile.h +++ b/src/IniFile.h @@ -1,14 +1,14 @@ // IniFile.cpp: Implementation of the CIniFile class. // Written by: Adam Clauss // Email: cabadam@tamu.edu -// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// You may use this class / code as you wish in your programs. Feel free to distribute it, and // email suggested changes to me. // // Rewritten by: Shane Hill -// Date: 21/08/2001 +// Date: 2001-08-21 // Email: Shane.Hill@dsto.defence.gov.au // Reason: Remove dependancy on MFC. Code should compile on any -// platform. Tested on Windows/Linux/Irix +// platform. Tested on Windows / Linux / Irix //////////////////////////////////////////////////////////////////////////////// /* @@ -108,7 +108,7 @@ public: // Gets value of [keyname] valuename =. // Overloaded to return string, int, and double. - // Returns defValue if key/value not found. + // Returns defValue if key / value not found. AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; AString GetValue (const int keyID, const int valueID, const AString & defValue = "") const; double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; @@ -217,7 +217,7 @@ public: -/** Reads the list of ports from the INI file, possibly upgrading from IPv4/IPv6-specific values into new version-agnostic value. +/** Reads the list of ports from the INI file, possibly upgrading from IPv4 / IPv6-specific values into new version-agnostic value. Reads the list of ports from a_PortsValueName. If that value doesn't exist or is empty, the list is combined from values in a_OldIPv4ValueName and a_OldIPv6ValueName; in this case the old values are removed from the INI file. If there is none of the three values or they are all empty, the default is used and stored in the Ports value. */ diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index 4959d52cc..24641dce6 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -64,7 +64,7 @@ public: } default: { - // Light a fire next to/on top of the block if air: + // Light a fire next to / on top of the block if air: AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h index 3440a7516..7eede5864 100644 --- a/src/Items/ItemLilypad.h +++ b/src/Items/ItemLilypad.h @@ -71,7 +71,7 @@ public: cBlockInfo::FullyOccupiesVoxel(a_CBBlockType) ) { - // Can't place lilypad on air/in another block! + // Can't place lilypad on air / in another block! return true; } m_HasHitFluid = true; diff --git a/src/Map.h b/src/Map.h index 3e775231a..a764eda50 100644 --- a/src/Map.h +++ b/src/Map.h @@ -140,7 +140,7 @@ public: /** Update a circular region around the specified player. */ void UpdateRadius(cPlayer & a_Player, unsigned int a_Radius); - /** Send next update packet to the specified player and remove invalid decorators/clients. */ + /** Send next update packet to the specified player and remove invalid decorators / clients. */ void UpdateClient(cPlayer * a_Player); // tolua_begin diff --git a/src/MobCensus.cpp b/src/MobCensus.cpp index 4109aff07..1a69d8370 100644 --- a/src/MobCensus.cpp +++ b/src/MobCensus.cpp @@ -19,8 +19,8 @@ void cMobCensus::CollectMob(cMonster & a_Monster, cChunk & a_Chunk, double a_Dis bool cMobCensus::IsCapped(cMonster::eFamily a_MobFamily) { - const int ratio = 319; // This should be 256 as we are only supposed to take account from chunks that are in 17x17 from a player - // but for now, we use all chunks loaded by players. that means 19 x 19 chunks. That's why we use 256 * (19*19) / (17*17) = 319 + const int ratio = 319; // This should be 256 as we are only supposed to take account from chunks that are in 17 x 17 from a player + // but for now, we use all chunks loaded by players. that means 19 x 19 chunks. That's why we use 256 * (19 * 19) / (17 * 17) = 319 // MG TODO : code the correct count if ((GetCapMultiplier(a_MobFamily) * GetNumChunks()) / ratio >= m_MobFamilyCollecter.GetNumberOfCollectedMobs(a_MobFamily)) { diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index a2295777a..5d20ba810 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -224,7 +224,7 @@ protected: Calls ResetPathFinding and sets m_IsFollowingPath to false */ void StopMovingToPosition(); - /** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */ + /** Sets the body yaw and head yaw / pitch based on next / ultimate destinations */ void SetPitchAndYawFromDestination(void); virtual void HandleFalling(void); diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index 0d903adb6..adae77984 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -12,7 +12,7 @@ Put this in your .cpp: */ #ifdef COMPILING_PATHFIND_DEBUGGER - /* Note: the COMPILING_PATHFIND_DEBUGGER flag is used by Native/WiseOldMan95 to debug + /* Note: the COMPILING_PATHFIND_DEBUGGER flag is used by Native / WiseOldMan95 to debug this class outside of MCServer. This preprocessor flag is never set when compiling MCServer. */ #include "PathFinderIrrlicht_Head.h" #endif diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp index 0249ab6c1..d11c47bc2 100644 --- a/src/Noise/Noise.cpp +++ b/src/Noise/Noise.cpp @@ -633,10 +633,10 @@ NOISE_DATATYPE cNoise::CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOIS }; const NOISE_DATATYPE FracX = (a_X) - BaseX; - const NOISE_DATATYPE x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX); - const NOISE_DATATYPE x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX); - const NOISE_DATATYPE x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX); - const NOISE_DATATYPE x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX); + const NOISE_DATATYPE x1interp1 = CubicInterpolate(points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX); + const NOISE_DATATYPE x1interp2 = CubicInterpolate(points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX); + const NOISE_DATATYPE x1interp3 = CubicInterpolate(points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX); + const NOISE_DATATYPE x1interp4 = CubicInterpolate(points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX); const NOISE_DATATYPE points2[4][4] = { @@ -646,45 +646,45 @@ NOISE_DATATYPE cNoise::CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOIS { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ), IntNoise3D(BaseX, BaseY + 2, BaseZ), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ), }, }; - const NOISE_DATATYPE x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX); - const NOISE_DATATYPE x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX); - const NOISE_DATATYPE x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX); - const NOISE_DATATYPE x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX); + const NOISE_DATATYPE x2interp1 = CubicInterpolate(points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX); + const NOISE_DATATYPE x2interp2 = CubicInterpolate(points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX); + const NOISE_DATATYPE x2interp3 = CubicInterpolate(points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX); + const NOISE_DATATYPE x2interp4 = CubicInterpolate(points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX); const NOISE_DATATYPE points3[4][4] = { - { IntNoise3D( BaseX-1, BaseY-1, BaseZ+1), IntNoise3D( BaseX, BaseY-1, BaseZ+1), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1), IntNoise3D( BaseX+2, BaseY-1, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY, BaseZ+1), IntNoise3D( BaseX, BaseY, BaseZ+1), IntNoise3D( BaseX+1, BaseY, BaseZ+1), IntNoise3D( BaseX+2, BaseY, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY+1, BaseZ+1), IntNoise3D( BaseX, BaseY+1, BaseZ+1), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1), IntNoise3D( BaseX+2, BaseY+1, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY+2, BaseZ+1), IntNoise3D( BaseX, BaseY+2, BaseZ+1), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1), IntNoise3D( BaseX+2, BaseY+2, BaseZ + 1), }, + { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ + 1), IntNoise3D(BaseX, BaseY - 1, BaseZ + 1), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ + 1), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ + 1), }, + { IntNoise3D(BaseX - 1, BaseY, BaseZ + 1), IntNoise3D(BaseX, BaseY, BaseZ + 1), IntNoise3D(BaseX + 1, BaseY, BaseZ + 1), IntNoise3D(BaseX + 2, BaseY, BaseZ + 1), }, + { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ + 1), IntNoise3D(BaseX, BaseY + 1, BaseZ + 1), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ + 1), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ + 1), }, + { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ + 1), IntNoise3D(BaseX, BaseY + 2, BaseZ + 1), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ + 1), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ + 1), }, }; - const NOISE_DATATYPE x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX); - const NOISE_DATATYPE x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX); - const NOISE_DATATYPE x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX); - const NOISE_DATATYPE x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX); + const NOISE_DATATYPE x3interp1 = CubicInterpolate(points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX); + const NOISE_DATATYPE x3interp2 = CubicInterpolate(points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX); + const NOISE_DATATYPE x3interp3 = CubicInterpolate(points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX); + const NOISE_DATATYPE x3interp4 = CubicInterpolate(points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX); const NOISE_DATATYPE points4[4][4] = { - { IntNoise3D( BaseX-1, BaseY-1, BaseZ+2), IntNoise3D( BaseX, BaseY-1, BaseZ+2), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY, BaseZ+2), IntNoise3D( BaseX, BaseY, BaseZ+2), IntNoise3D( BaseX+1, BaseY, BaseZ+2), IntNoise3D( BaseX+2, BaseY, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY+1, BaseZ+2), IntNoise3D( BaseX, BaseY+1, BaseZ+2), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY+2, BaseZ+2), IntNoise3D( BaseX, BaseY+2, BaseZ+2), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2), }, + { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ + 2), IntNoise3D(BaseX, BaseY - 1, BaseZ + 2), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ + 2), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ + 2), }, + { IntNoise3D(BaseX - 1, BaseY, BaseZ + 2), IntNoise3D(BaseX, BaseY, BaseZ + 2), IntNoise3D(BaseX + 1, BaseY, BaseZ + 2), IntNoise3D(BaseX + 2, BaseY, BaseZ + 2), }, + { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ + 2), IntNoise3D(BaseX, BaseY + 1, BaseZ + 2), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ + 2), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ + 2), }, + { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ + 2), IntNoise3D(BaseX, BaseY + 2, BaseZ + 2), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ + 2), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ + 2), }, }; - const NOISE_DATATYPE x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX); - const NOISE_DATATYPE x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX); - const NOISE_DATATYPE x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX); - const NOISE_DATATYPE x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX); + const NOISE_DATATYPE x4interp1 = CubicInterpolate(points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX); + const NOISE_DATATYPE x4interp2 = CubicInterpolate(points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX); + const NOISE_DATATYPE x4interp3 = CubicInterpolate(points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX); + const NOISE_DATATYPE x4interp4 = CubicInterpolate(points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX); const NOISE_DATATYPE FracY = (a_Y) - BaseY; - const NOISE_DATATYPE yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY); - const NOISE_DATATYPE yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY); - const NOISE_DATATYPE yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY); - const NOISE_DATATYPE yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY); + const NOISE_DATATYPE yinterp1 = CubicInterpolate(x1interp1, x1interp2, x1interp3, x1interp4, FracY); + const NOISE_DATATYPE yinterp2 = CubicInterpolate(x2interp1, x2interp2, x2interp3, x2interp4, FracY); + const NOISE_DATATYPE yinterp3 = CubicInterpolate(x3interp1, x3interp2, x3interp3, x3interp4, FracY); + const NOISE_DATATYPE yinterp4 = CubicInterpolate(x4interp1, x4interp2, x4interp3, x4interp4, FracY); const NOISE_DATATYPE FracZ = (a_Z) - BaseZ; - return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ); + return CubicInterpolate(yinterp1, yinterp2, yinterp3, yinterp4, FracZ); } diff --git a/src/OSSupport/CriticalSection.h b/src/OSSupport/CriticalSection.h index d52f049d2..a95a9a0cd 100644 --- a/src/OSSupport/CriticalSection.h +++ b/src/OSSupport/CriticalSection.h @@ -13,7 +13,7 @@ public: void Lock(void); void Unlock(void); - // IsLocked/IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined + // IsLocked / IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined // The fake versions (in Release) will not effect the program in any way #ifdef _DEBUG cCriticalSection(void); diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index dc6543180..1b5e71a17 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -62,7 +62,7 @@ public: { fmRead, // Read-only. If the file doesn't exist, object will not be valid fmWrite, // Write-only. If the file already exists, it will be overwritten - fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmReadWrite, // Read / write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file } ; diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 95a935bbe..1162d7fc6 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -162,7 +162,7 @@ public: /** Returns the local port to which the underlying socket is bound. */ virtual UInt16 GetPort(void) const = 0; - /** Sends the specified payload in a single UDP datagram to the specified host+port combination. + /** Sends the specified payload in a single UDP datagram to the specified host + port combination. Note that in order to send to a broadcast address, you need to call EnableBroadcasts() first. */ virtual bool Send(const AString & a_Payload, const AString & a_Host, UInt16 a_Port) = 0; diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 570754204..0d1441500 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -659,7 +659,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery) a_NamesToQuery.erase(a_NamesToQuery.begin(), itr); Json::FastWriter Writer; AString RequestBody = Writer.write(root); - + // Create the HTTP request: AString Request; Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding @@ -667,7 +667,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery) Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Type: application/json\r\n"; - Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); + Request += Printf("Content-Length: %u\r\n", static_cast(RequestBody.length())); Request += "\r\n"; Request += RequestBody; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 57631c37d..799c021f3 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -492,7 +492,7 @@ void cProtocol172::SendEntityVelocity(const cEntity & a_Entity) cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick + // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); @@ -2514,7 +2514,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings { - AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;) + AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent / backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;) } a_Item.m_Lore = Lore; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 628d8f528..1d83be8dd 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -479,7 +479,7 @@ void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick + // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick Pkt.WriteBEInt16((short)(a_Entity.GetSpeedX() * 400)); Pkt.WriteBEInt16((short)(a_Entity.GetSpeedY() * 400)); Pkt.WriteBEInt16((short)(a_Entity.GetSpeedZ() * 400)); @@ -2754,7 +2754,7 @@ void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings { - AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;) + AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent / backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;) } a_Item.m_Lore = Lore; diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 54fef5ce7..ee39026ea 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -2153,7 +2153,7 @@ void cRankManager::ClearPlayerRanks(void) } catch (SQLite::Exception & ex) { - LOGWARNING("%s: Failed to remove/clear all players: %s", __FUNCTION__, ex.what()); + LOGWARNING("%s: Failed to remove / clear all players: %s", __FUNCTION__, ex.what()); } } diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index 8e1be5e6b..0eac61a03 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -47,7 +47,7 @@ protected: /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */ bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - /** Checks if the specified block should harden (Water/Lava interaction) and if so, converts it to a suitable block. + /** Checks if the specified block should harden (Water / Lava interaction) and if so, converts it to a suitable block. Returns whether the block was changed or not. */ bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta); diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 40be9c582..7f320af0d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -366,7 +366,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_R if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last) { if ( - IsMechanism(Type) && // Is it a mechanism? Not block/other torch etc. + IsMechanism(Type) && // Is it a mechanism? Not block / other torch etc. (!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on ) { @@ -1600,7 +1600,7 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB if ((OtherRepeaterDir & 0x03) == 0x3) { return true; - } // If so, I am latched/locked + } // If so, I am latched / locked } // Check if western(left) neighbor is a powered on repeater who is facing us @@ -1612,7 +1612,7 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB if ((OtherRepeaterDir & 0x03) == 0x1) { return true; - } // If so, I am latched/locked + } // If so, I am latched / locked } break; @@ -1634,7 +1634,7 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB if ((OtherRepeaterDir & 0x30) == 0x00) { return true; - } // If so, am latched/locked + } // If so, I am latched / locked } // Check if northern(up) neighbor is a powered on repeater who is facing us @@ -1646,7 +1646,7 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB if ((OtherRepeaterDir & 0x03) == 0x02) { return true; - } // If so, I am latched/locked + } // If so, I am latched / locked } break; diff --git a/src/UI/DropSpenserWindow.cpp b/src/UI/DropSpenserWindow.cpp index aeb7c64b7..121836e40 100644 --- a/src/UI/DropSpenserWindow.cpp +++ b/src/UI/DropSpenserWindow.cpp @@ -1,7 +1,7 @@ // DropSpenserWindow.cpp -// Representing the UI window for the dropper/dispenser block +// Representing the UI window for the dropper / dispenser block #include "Globals.h" #include "DropSpenserWindow.h" diff --git a/src/UI/DropSpenserWindow.h b/src/UI/DropSpenserWindow.h index edff936e5..cfc040493 100644 --- a/src/UI/DropSpenserWindow.h +++ b/src/UI/DropSpenserWindow.h @@ -1,7 +1,7 @@ // DropSpenserWindow.h -// Representing the UI window for the dropper/dispenser block +// Representing the UI window for the dropper / dispenser block diff --git a/src/UI/FurnaceWindow.cpp b/src/UI/FurnaceWindow.cpp index 132439ff3..a4e852fd8 100644 --- a/src/UI/FurnaceWindow.cpp +++ b/src/UI/FurnaceWindow.cpp @@ -41,7 +41,7 @@ void cFurnaceWindow::DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & } else { - // Furnace Input/Fuel Slot + // Furnace Input / Fuel Slot AreasInOrder.push_back(m_SlotAreas[1]); /* Inventory */ AreasInOrder.push_back(m_SlotAreas[2]); /* Hotbar */ super::DistributeStackToAreas(a_ItemStack, a_Player, AreasInOrder, a_ShouldApply, false); diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 0e7ba2a50..f6a9972d6 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -306,7 +306,7 @@ public: void UpdateResult(cPlayer & a_Player); protected: - /** The maximum cost of repairing/renaming in the anvil. */ + /** The maximum cost of repairing / renaming in the anvil. */ int m_MaximumCost; /** The stack size of the second item where was used for repair */ diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h index 56022849e..a04a613d5 100644 --- a/src/VoronoiMap.h +++ b/src/VoronoiMap.h @@ -59,7 +59,7 @@ protected: cNoise m_Noise2; cNoise m_Noise3; - /** Size of the Voronoi cells (avg X/Y distance between the seeds). Expected to be at least 2. */ + /** Size of the Voronoi cells (avg X / Y distance between the seeds). Expected to be at least 2. */ int m_CellSize; /** The amount that the cell seeds may be offset from the grid. diff --git a/src/World.cpp b/src/World.cpp index 6c2e31965..d0406f078 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -176,7 +176,7 @@ protected: { float PercentDone = static_cast(m_NumPrepared * 100) / m_MaxIdx; float ChunkSpeed = static_cast((m_NumPrepared - m_LastReportChunkCount) * 1000) / std::chrono::duration_cast(Now - m_LastReportTime).count(); - LOG("Preparing spawn (%s): %.02f%% (%d/%d; %.02f chunks/s)", + LOG("Preparing spawn (%s): %.02f%% (%d/%d; %.02f chunks / sec)", m_World.GetName().c_str(), PercentDone, m_NumPrepared, m_MaxIdx, ChunkSpeed ); m_LastReportTime = Now; @@ -767,7 +767,7 @@ eWeather cWorld::ChooseNewWeather() case eWeather_Rain: { - // 1/8 chance of turning into a thunderstorm + // 1 / 8 chance of turning into a thunderstorm return ((m_TickRand.randInt() % 256) < 32) ? eWeather_ThunderStorm : eWeather_Sunny; } } diff --git a/src/World.h b/src/World.h index 624262cd3..6c0548ae6 100644 --- a/src/World.h +++ b/src/World.h @@ -152,10 +152,10 @@ public: int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } - /** Is the daylight cyclus enabled? */ + /** Is the daylight cycle enabled? */ virtual bool IsDaylightCycleEnabled(void) const { return m_IsDaylightCycleEnabled; } - /** Sets the daylight cyclus to true/false. */ + /** Sets the daylight cycle to true / false. */ virtual void SetDaylightCycleEnabled(bool a_IsDaylightCycleEnabled) { m_IsDaylightCycleEnabled = a_IsDaylightCycleEnabled; @@ -1067,7 +1067,7 @@ private: /** Handles the weather in each tick */ void TickWeather(float a_Dt); - /** Handles the mob spawning/moving/destroying each tick */ + /** Handles the mob spawning / moving / destroying each tick */ void TickMobs(std::chrono::milliseconds a_Dt); /** Executes all tasks queued onto the tick thread */ diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index c6225eacf..35e47c8e4 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -164,7 +164,7 @@ public: /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; - /** Returns the child tag of the specified path (Name1/Name2/Name3...), or -1 if no such tag. */ + /** Returns the child tag of the specified path (Name1 / Name2 / Name3...), or -1 if no such tag. */ int FindTagByPath(int a_Tag, const AString & a_Path) const; eTagType GetType(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_Type; } diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index f2d35b318..6f0449041 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -19,9 +19,9 @@ cMapSerializer::cMapSerializer(const AString& a_WorldName, cMap * a_Map) : m_Map(a_Map) { AString DataPath; - Printf(DataPath, "%s/data", a_WorldName.c_str()); + Printf(DataPath, "%s%cdata", a_WorldName.c_str(), cFile::PathSeparator); - Printf(m_Path, "%s/map_%i.dat", DataPath.c_str(), a_Map->GetID()); + Printf(m_Path, "%s%cmap_%i.dat", DataPath.c_str(), cFile::PathSeparator, a_Map->GetID()); cFile::CreateFolder(FILE_IO_PREFIX + DataPath); } @@ -203,9 +203,9 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) cIDCountSerializer::cIDCountSerializer(const AString & a_WorldName) : m_MapCount(0) { AString DataPath; - Printf(DataPath, "%s/data", a_WorldName.c_str()); + Printf(DataPath, "%s%cdata", a_WorldName.c_str(), cFile::PathSeparator); - Printf(m_Path, "%s/idcounts.dat", DataPath.c_str()); + Printf(m_Path, "%s%cidcounts.dat", DataPath.c_str(), cFile::PathSeparator); cFile::CreateFolder(FILE_IO_PREFIX + DataPath); } diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 404604382..0d8730e49 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -18,7 +18,7 @@ cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScore : m_ScoreBoard(a_ScoreBoard) { AString DataPath; - Printf(DataPath, "%s/data", a_WorldName.c_str()); + Printf(DataPath, "%s%cdata", a_WorldName.c_str(), cFile::PathSeparator); m_Path = DataPath + "/scoreboard.dat"; diff --git a/src/WorldStorage/StatSerializer.cpp b/src/WorldStorage/StatSerializer.cpp index 74113941c..99a702c39 100644 --- a/src/WorldStorage/StatSerializer.cpp +++ b/src/WorldStorage/StatSerializer.cpp @@ -18,7 +18,7 @@ cStatSerializer::cStatSerializer(const AString & a_WorldName, const AString & a_ // inside the folder of the default world. AString StatsPath; - Printf(StatsPath, "%s/stats", a_WorldName.c_str()); + Printf(StatsPath, "%s%cstats", a_WorldName.c_str(), cFile::PathSeparator); m_Path = StatsPath + "/" + a_PlayerName + ".json"; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 948a0c9a0..f389e7cbf 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -95,7 +95,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : { // Create a level.dat file for mapping tools, if it doesn't already exist: AString fnam; - Printf(fnam, "%s/level.dat", a_World->GetName().c_str()); + Printf(fnam, "%s%clevel.dat", a_World->GetName().c_str(), cFile::PathSeparator); if (!cFile::Exists(fnam)) { cFastNBTWriter Writer; @@ -251,7 +251,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) // Load it anew: AString FileName; - Printf(FileName, "%s/region", m_World->GetName().c_str()); + Printf(FileName, "%s%cregion", m_World->GetName().c_str(), cFile::PathSeparator); cFile::CreateFolder(FILE_IO_PREFIX + FileName); AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ); cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ); @@ -323,7 +323,7 @@ bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT) { - // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data) + // The data arrays, in MCA-native y / z / x ordering (will be reordered for the final chunk data) cChunkDef::BlockTypes BlockTypes; cChunkDef::BlockNibbles MetaData; cChunkDef::BlockNibbles BlockLight; @@ -879,7 +879,7 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI Beacon->SetSecondaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); } - // We are better than mojang, we load/save the beacon inventory! + // We are better than mojang, we load / save the beacon inventory! int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items >= 0) && (a_NBT.GetType(Items) == TAG_List)) { diff --git a/src/XMLParser.h b/src/XMLParser.h index ea341bce6..90e499785 100644 --- a/src/XMLParser.h +++ b/src/XMLParser.h @@ -168,9 +168,9 @@ public: protected: - // Parser callback enable/disable methods: + // Parser callback enable / disable methods: - // @cmember Enable/Disable the start element handler + // @cmember Enable / Disable the start element handler void EnableStartElementHandler (bool fEnable = true) { @@ -178,7 +178,7 @@ protected: XML_SetStartElementHandler (m_p, fEnable ? StartElementHandler : nullptr); } - // @cmember Enable/Disable the end element handler + // @cmember Enable / Disable the end element handler void EnableEndElementHandler (bool fEnable = true) { @@ -186,7 +186,7 @@ protected: XML_SetEndElementHandler (m_p, fEnable ? EndElementHandler : nullptr); } - // @cmember Enable/Disable the element handlers + // @cmember Enable / Disable the element handlers void EnableElementHandler (bool fEnable = true) { @@ -195,7 +195,7 @@ protected: EnableEndElementHandler (fEnable); } - // @cmember Enable/Disable the character data handler + // @cmember Enable / Disable the character data handler void EnableCharacterDataHandler (bool fEnable = true) { @@ -203,7 +203,7 @@ protected: XML_SetCharacterDataHandler (m_p, fEnable ? CharacterDataHandler : nullptr); } - // @cmember Enable/Disable the processing instruction handler + // @cmember Enable / Disable the processing instruction handler void EnableProcessingInstructionHandler (bool fEnable = true) { @@ -211,7 +211,7 @@ protected: XML_SetProcessingInstructionHandler (m_p, fEnable ? ProcessingInstructionHandler : nullptr); } - // @cmember Enable/Disable the comment handler + // @cmember Enable / Disable the comment handler void EnableCommentHandler (bool fEnable = true) { @@ -219,7 +219,7 @@ protected: XML_SetCommentHandler (m_p, fEnable ? CommentHandler : nullptr); } - // @cmember Enable/Disable the start CDATA section handler + // @cmember Enable / Disable the start CDATA section handler void EnableStartCdataSectionHandler (bool fEnable = true) { @@ -227,7 +227,7 @@ protected: XML_SetStartCdataSectionHandler (m_p, fEnable ? StartCdataSectionHandler : nullptr); } - // @cmember Enable/Disable the end CDATA section handler + // @cmember Enable / Disable the end CDATA section handler void EnableEndCdataSectionHandler (bool fEnable = true) { @@ -235,7 +235,7 @@ protected: XML_SetEndCdataSectionHandler (m_p, fEnable ? EndCdataSectionHandler : nullptr); } - // @cmember Enable/Disable the CDATA section handlers + // @cmember Enable / Disable the CDATA section handlers void EnableCdataSectionHandler (bool fEnable = true) { @@ -244,7 +244,7 @@ protected: EnableEndCdataSectionHandler (fEnable); } - // @cmember Enable/Disable default handler + // @cmember Enable / Disable default handler void EnableDefaultHandler (bool fEnable = true, bool fExpand = true) { @@ -259,7 +259,7 @@ protected: } } - // @cmember Enable/Disable external entity ref handler + // @cmember Enable / Disable external entity ref handler void EnableExternalEntityRefHandler (bool fEnable = true) { @@ -267,7 +267,7 @@ protected: XML_SetExternalEntityRefHandler (m_p, fEnable ? ExternalEntityRefHandler : nullptr); } - // @cmember Enable/Disable unknown encoding handler + // @cmember Enable / Disable unknown encoding handler void EnableUnknownEncodingHandler (bool fEnable = true) { @@ -275,7 +275,7 @@ protected: XML_SetUnknownEncodingHandler (m_p, fEnable ? UnknownEncodingHandler : nullptr); } - // @cmember Enable/Disable start namespace handler + // @cmember Enable / Disable start namespace handler void EnableStartNamespaceDeclHandler (bool fEnable = true) { @@ -283,7 +283,7 @@ protected: XML_SetStartNamespaceDeclHandler (m_p, fEnable ? StartNamespaceDeclHandler : nullptr); } - // @cmember Enable/Disable end namespace handler + // @cmember Enable / Disable end namespace handler void EnableEndNamespaceDeclHandler (bool fEnable = true) { @@ -291,7 +291,7 @@ protected: XML_SetEndNamespaceDeclHandler (m_p, fEnable ? EndNamespaceDeclHandler : nullptr); } - // @cmember Enable/Disable namespace handlers + // @cmember Enable / Disable namespace handlers void EnableNamespaceDeclHandler (bool fEnable = true) { @@ -299,7 +299,7 @@ protected: EnableEndNamespaceDeclHandler (fEnable); } - // @cmember Enable/Disable the XML declaration handler + // @cmember Enable / Disable the XML declaration handler void EnableXmlDeclHandler (bool fEnable = true) { @@ -307,7 +307,7 @@ protected: XML_SetXmlDeclHandler (m_p, fEnable ? XmlDeclHandler : nullptr); } - // @cmember Enable/Disable the start DOCTYPE declaration handler + // @cmember Enable / Disable the start DOCTYPE declaration handler void EnableStartDoctypeDeclHandler (bool fEnable = true) { @@ -315,7 +315,7 @@ protected: XML_SetStartDoctypeDeclHandler (m_p, fEnable ? StartDoctypeDeclHandler : nullptr); } - // @cmember Enable/Disable the end DOCTYPE declaration handler + // @cmember Enable / Disable the end DOCTYPE declaration handler void EnableEndDoctypeDeclHandler (bool fEnable = true) { @@ -324,7 +324,7 @@ protected: fEnable ? EndDoctypeDeclHandler : nullptr); } - // @cmember Enable/Disable the DOCTYPE declaration handler + // @cmember Enable / Disable the DOCTYPE declaration handler void EnableDoctypeDeclHandler (bool fEnable = true) { -- cgit v1.2.3 From 846d16315a8b5a81fbc37d66da4d1254038ec494 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 9 May 2015 11:16:56 +0200 Subject: CheckBasicStyle: checks spaces around * and &. --- src/Bindings/LuaWindow.cpp | 6 +++--- src/Bindings/ManualBindings.cpp | 12 ++++++------ src/CheckBasicStyle.lua | 12 ++++++++++-- src/Chunk.cpp | 18 +++++++++--------- src/Chunk.h | 4 ++-- src/ChunkMap.cpp | 18 +++++++++--------- src/ChunkMap.h | 13 +++++++------ src/ChunkSender.h | 2 +- src/Enchantments.h | 4 ++-- src/Endianness.h | 2 +- src/Generating/Caves.cpp | 2 +- src/Inventory.cpp | 2 +- src/Inventory.h | 2 +- src/Items/ItemChest.h | 2 +- src/Items/ItemHandler.cpp | 2 +- src/Logger.h | 8 ++++---- src/Map.cpp | 2 +- src/MobCensus.h | 4 ++-- src/MobProximityCounter.cpp | 6 +++++- src/MobProximityCounter.h | 14 +++++++------- src/MobSpawner.cpp | 4 ++-- src/MobSpawner.h | 2 +- src/MonsterConfig.h | 2 +- src/OSSupport/Semaphore.h | 2 +- src/Protocol/ChunkDataSerializer.cpp | 4 ++-- src/Root.cpp | 4 ++-- src/Root.h | 2 +- src/Scoreboard.cpp | 8 ++++---- src/Scoreboard.h | 15 ++++++--------- src/StringUtils.h | 2 +- src/Tracer.h | 5 +++-- src/UI/MinecartWithChestWindow.h | 2 +- src/WebAdmin.cpp | 2 +- src/World.cpp | 2 +- src/WorldStorage/EnchantmentSerializer.cpp | 4 ++-- src/WorldStorage/EnchantmentSerializer.h | 4 ++-- src/WorldStorage/MapSerializer.cpp | 4 ++-- src/WorldStorage/MapSerializer.h | 2 +- src/WorldStorage/ScoreboardSerializer.cpp | 6 +++--- src/WorldStorage/ScoreboardSerializer.h | 4 ++-- src/WorldStorage/StatSerializer.h | 2 +- src/WorldStorage/WSSAnvil.cpp | 2 +- 42 files changed, 115 insertions(+), 104 deletions(-) diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index d4014059b..5f7832ef5 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -159,7 +159,7 @@ void cLuaWindow::Destroy(void) m_Plugin->Unreference(m_LuaRef); } - // Lua will take care of this object, it will garbage-collect it, so we *must not* delete it! + // Lua will take care of this object, it will garbage-collect it, so we must not delete it! m_IsDestroyed = false; } @@ -167,10 +167,10 @@ void cLuaWindow::Destroy(void) -void cLuaWindow::DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer& a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) +void cLuaWindow::DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) { cSlotAreas Areas; - for (auto Area : m_SlotAreas) + for (auto && Area : m_SlotAreas) { if (Area != a_ClickedArea) { diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20042a780..10f5ecb94 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2557,8 +2557,8 @@ static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, for (std::map::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it) { - const char* key = it->first.c_str(); - const char* value = it->second.c_str(); + const char * key = it->first.c_str(); + const char * value = it->second.c_str(); lua_pushstring(tolua_S, key); lua_pushstring(tolua_S, value); lua_settable(tolua_S, top); @@ -2573,7 +2573,7 @@ static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); + HTTPRequest * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); return tolua_push_StringStringMap(tolua_S, self->Params); } @@ -2583,7 +2583,7 @@ static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); + HTTPRequest * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); return tolua_push_StringStringMap(tolua_S, self->PostParams); } @@ -2593,8 +2593,8 @@ static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); - std::map< std::string, HTTPFormData >& FormData = self->FormData; + HTTPRequest * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); + std::map & FormData = self->FormData; lua_newtable(tolua_S); int top = lua_gettop(tolua_S); diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 09e64b954..133446350 100755 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -164,12 +164,20 @@ local g_ViolationPatterns = -- Cannot check spaces around "-", because the minus is sometimes used as a hyphen between-words -- Check spaces around "*": - {"^[a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, - {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, + {"^[a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%*[a-zA-Z0-9]+", "Add space around *"}, + {"^[a-zB-Z0-9]+%* [a-zA-Z0-9]+", "Add space before *"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zB-Z0-9]+%* [a-zA-Z0-9]+", "Add space before *"}, -- Check spaces around "/": {"^[a-zA-Z0-9]+%/[a-zA-Z0-9]+", "Add space around /"}, {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%/[a-zA-Z0-9]+", "Add space around /"}, + + -- Check spaces around "&": + {"^[a-zA-Z0-9]+%&[a-zA-Z0-9]+", "Add space around /"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%&[a-zA-Z0-9]+", "Add space around /"}, + {"^[a-zA-Z0-9]+%& [a-zA-Z0-9]+", "Add space before &"}, + {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%& [a-zA-Z0-9]+", "Add space before &"}, } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index bed5aa991..ed5a1b12a 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -472,26 +472,26 @@ void cChunk::Stay(bool a_Stay) -void cChunk::CollectMobCensus(cMobCensus& toFill) +void cChunk::CollectMobCensus(cMobCensus & toFill) { toFill.CollectSpawnableChunk(*this); - std::list playerPositions; - cPlayer* currentPlayer; - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) + std::list playerPositions; + cPlayer * currentPlayer; + for (auto itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) { currentPlayer = (*itr)->GetPlayer(); playerPositions.push_back(&(currentPlayer->GetPosition())); } Vector3d currentPosition; - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + for (auto itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { // LOGD("Counting entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); if ((*itr)->IsMob()) { - cMonster& Monster = (cMonster&)(**itr); + auto & Monster = reinterpret_cast(**itr); currentPosition = Monster.GetPosition(); - for (std::list::const_iterator itr2 = playerPositions.begin(); itr2 != playerPositions.end(); ++itr2) + for (auto itr2 = playerPositions.cbegin(); itr2 != playerPositions.cend(); ++itr2) { toFill.CollectMob(Monster, *this, (currentPosition - **itr2).SqrLength()); } @@ -531,7 +531,7 @@ void cChunk::GetRandomBlockCoords(int & a_X, int & a_Y, int & a_Z) -void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner) +void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) { int CenterX, CenterY, CenterZ; GetRandomBlockCoords(CenterX, CenterY, CenterZ); @@ -1839,7 +1839,7 @@ bool cChunk::SetSignLines(int a_PosX, int a_PosY, int a_PosZ, const AString & a_ -void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity) +void cChunk::RemoveBlockEntity(cBlockEntity * a_BlockEntity) { MarkDirty(); m_BlockEntities.remove(a_BlockEntity); diff --git a/src/Chunk.h b/src/Chunk.h index 58f6ba707..f57769107 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -155,10 +155,10 @@ public: void Stay(bool a_Stay = true); /** Recence all mobs proximities to players in order to know what to do with them */ - void CollectMobCensus(cMobCensus& toFill); + void CollectMobCensus(cMobCensus & toFill); /** Try to Spawn Monsters inside chunk */ - void SpawnMobs(cMobSpawner& a_MobSpawner); + void SpawnMobs(cMobSpawner & a_MobSpawner); void Tick(std::chrono::milliseconds a_Dt); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index edff6baf1..44acc2013 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -65,7 +65,7 @@ cChunkMap::~cChunkMap() -void cChunkMap::RemoveLayer( cChunkLayer* a_Layer) +void cChunkMap::RemoveLayer(cChunkLayer * a_Layer) { cCSLock Lock(m_CSLayers); m_Layers.remove(a_Layer); @@ -2716,12 +2716,12 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) -void cChunkMap::CollectMobCensus(cMobCensus& a_ToFill) +void cChunkMap::CollectMobCensus(cMobCensus & a_ToFill) { cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + for (auto && layer: m_Layers) { - (*itr)->CollectMobCensus(a_ToFill); + layer->CollectMobCensus(a_ToFill); } // for itr - m_Layers } @@ -2730,12 +2730,12 @@ void cChunkMap::CollectMobCensus(cMobCensus& a_ToFill) -void cChunkMap::SpawnMobs(cMobSpawner& a_MobSpawner) +void cChunkMap::SpawnMobs(cMobSpawner & a_MobSpawner) { cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + for (auto && layer: m_Layers) { - (*itr)->SpawnMobs(a_MobSpawner); + layer->SpawnMobs(a_MobSpawner); } // for itr - m_Layers } @@ -2936,7 +2936,7 @@ cChunk * cChunkMap::cChunkLayer::FindChunk(int a_ChunkX, int a_ChunkZ) -void cChunkMap::cChunkLayer::CollectMobCensus(cMobCensus& a_ToFill) +void cChunkMap::cChunkLayer::CollectMobCensus(cMobCensus & a_ToFill) { for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { @@ -2955,7 +2955,7 @@ void cChunkMap::cChunkLayer::CollectMobCensus(cMobCensus& a_ToFill) -void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner& a_MobSpawner) +void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner & a_MobSpawner) { for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { diff --git a/src/ChunkMap.h b/src/ChunkMap.h index e9f1b94c0..35f66f339 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -64,7 +64,7 @@ public: static const int LAYER_SIZE = 32; - cChunkMap(cWorld* a_World); + cChunkMap(cWorld * a_World); ~cChunkMap(); // Broadcast respective packets to all clients of the chunk where the event is taking place @@ -364,11 +364,11 @@ public: /** Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call */ void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); - /** Make a Mob census, of all mobs, their family, their chunk and theyr distance to closest player */ - void CollectMobCensus(cMobCensus& a_ToFill); + /** Make a Mob census, of all mobs, their family, their chunk and their distance to closest player */ + void CollectMobCensus(cMobCensus & a_ToFill); /** Try to Spawn Monsters inside all Chunks */ - void SpawnMobs(cMobSpawner& a_MobSpawner); + void SpawnMobs(cMobSpawner & a_MobSpawner); void Tick(std::chrono::milliseconds a_Dt); @@ -433,9 +433,10 @@ private: void UnloadUnusedChunks(void); /** Collect a mob census, of all mobs, their megatype, their chunk and their distance o closest player */ - void CollectMobCensus(cMobCensus& a_ToFill); + void CollectMobCensus(cMobCensus & a_ToFill); + /** Try to Spawn Monsters inside all Chunks */ - void SpawnMobs(cMobSpawner& a_MobSpawner); + void SpawnMobs(cMobSpawner & a_MobSpawner); void Tick(std::chrono::milliseconds a_Dt); diff --git a/src/ChunkSender.h b/src/ChunkSender.h index 7cd7ddd86..8b187c5f9 100644 --- a/src/ChunkSender.h +++ b/src/ChunkSender.h @@ -13,7 +13,7 @@ And once they do, it requests the chunk data and sends it all away, either sends to a specific client (QueueSendChunkTo) Chunk data is queried using the cChunkDataCallback interface. It is cached inside the ChunkSender object during the query and then processed after the query ends. -Note that the data needs to be compressed only *after* the query finishes, +Note that the data needs to be compressed only after the query finishes, because the query callbacks run with ChunkMap's CS locked. A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient(); diff --git a/src/Enchantments.h b/src/Enchantments.h index 9c1c54ae9..9d3f342d4 100644 --- a/src/Enchantments.h +++ b/src/Enchantments.h @@ -138,10 +138,10 @@ public: bool operator !=(const cEnchantments & a_Other) const; /** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */ - friend void EnchantmentSerializer::WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); + friend void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); /** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */ - friend void EnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); + friend void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); protected: /** Maps enchantment ID -> enchantment level */ diff --git a/src/Endianness.h b/src/Endianness.h index ed9637fcc..a415903a5 100644 --- a/src/Endianness.h +++ b/src/Endianness.h @@ -21,7 +21,7 @@ inline UInt64 HostToNetwork8(const void * a_Value) -inline UInt32 HostToNetwork4(const void* a_Value) +inline UInt32 HostToNetwork4(const void * a_Value) { UInt32 buf; memcpy( &buf, a_Value, sizeof( buf)); diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 0a9b170fa..0a3673711 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -529,7 +529,7 @@ void cCaveTunnel::ProcessChunk( /* #ifdef _DEBUG - // For debugging purposes, outline the shape of the cave using glowstone, *after* carving the entire cave: + // For debugging purposes, outline the shape of the cave using glowstone, after carving the entire cave: for (cCaveDefPoints::const_iterator itr = m_Points.begin(), end = m_Points.end(); itr != end; ++itr) { int DifX = itr->m_BlockX - BlockStartX; // substitution for faster calc diff --git a/src/Inventory.cpp b/src/Inventory.cpp index fba6f4aea..c595da5b0 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -499,7 +499,7 @@ int cInventory::ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum) #if 0 -bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */) +bool cInventory::AddToBar(cItem & a_Item, const int a_Offset, const int a_Size, bool * a_bChangedSlots, int a_Mode /* = 0 */) { // Fill already present stacks if (a_Mode < 2) diff --git a/src/Inventory.h b/src/Inventory.h index 311f64562..b2a8f658b 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -171,7 +171,7 @@ public: bool LoadFromJson(Json::Value & a_Value); protected: - bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0); + bool AddToBar(cItem & a_Item, const int a_Offset, const int a_Size, bool * a_bChangedSlots, int a_Mode = 0); cItemGrid m_ArmorSlots; cItemGrid m_InventorySlots; diff --git a/src/Items/ItemChest.h b/src/Items/ItemChest.h index b6579c423..1d23975cd 100644 --- a/src/Items/ItemChest.h +++ b/src/Items/ItemChest.h @@ -78,7 +78,7 @@ public: !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta) ) { - // Tried to place a block *into* another? + // Tried to place a block into another? // Happens when you place a block aiming at side of block with a torch on it or stem beside it return false; } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 7328456b4..b7f89809e 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -362,7 +362,7 @@ bool cItemHandler::OnPlayerPlace( !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta) ) { - // Tried to place a block *into* another? + // Tried to place a block into another? // Happens when you place a block aiming at side of block with a torch on it or stem beside it return false; } diff --git a/src/Logger.h b/src/Logger.h index 5e65de8a8..176c6e810 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -46,10 +46,10 @@ private: -extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2); +extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2); +extern void LOGWARN (const char * a_Format, ...) FORMATSTRING(1, 2); +extern void LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/Map.cpp b/src/Map.cpp index 5e57cc8ec..5f296a5b2 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -591,7 +591,7 @@ void cMap::SendTo(cClientHandle & a_Client) for (unsigned int i = 0; i < m_Width; ++i) { - const Byte* Colors = &m_Data[i * m_Height]; + const Byte * Colors = &m_Data[i * m_Height]; a_Client.SendMapColumn(m_ID, i, 0, Colors, m_Height, m_Scale); } diff --git a/src/MobCensus.h b/src/MobCensus.h index e3892bec6..3dc7b2a8e 100644 --- a/src/MobCensus.h +++ b/src/MobCensus.h @@ -32,8 +32,8 @@ public: // MG TODO : code the correct rule (not loaded chunk but short distant from players) void CollectSpawnableChunk(cChunk & a_Chunk); - /// Collect a mob - it's distance to player, it's family ... - void CollectMob(cMonster& a_Monster, cChunk& a_Chunk, double a_Distance); + /// Collect a mob - its distance to player, its family ... + void CollectMob(cMonster & a_Monster, cChunk & a_Chunk, double a_Distance); /// Returns true if the family is capped (i.e. there are more mobs of this family than max) bool IsCapped(cMonster::eFamily a_MobFamily); diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp index cfd52440b..1bdac2f88 100644 --- a/src/MobProximityCounter.cpp +++ b/src/MobProximityCounter.cpp @@ -6,7 +6,11 @@ #include "Entities/Entity.h" #include "Chunk.h" -void cMobProximityCounter::CollectMob(cEntity& a_Monster, cChunk& a_Chunk, double a_Distance) + + + + +void cMobProximityCounter::CollectMob(cEntity & a_Monster, cChunk & a_Chunk, double a_Distance) { // LOGD("Collecting monster %s, with distance %f", a_Monster->GetClass(), a_Distance); tMonsterToDistance::iterator it = m_MonsterToDistance.find(&a_Monster); diff --git a/src/MobProximityCounter.h b/src/MobProximityCounter.h index 2dabeaa21..a3c0c125a 100644 --- a/src/MobProximityCounter.h +++ b/src/MobProximityCounter.h @@ -16,19 +16,19 @@ protected : // structs used for later maps (see m_MonsterToDistance and m_DistanceToMonster) struct sDistanceAndChunk { - sDistanceAndChunk(double a_Distance, cChunk& a_Chunk) : m_Distance(a_Distance), m_Chunk(&a_Chunk) {} + sDistanceAndChunk(double a_Distance, cChunk & a_Chunk) : m_Distance(a_Distance), m_Chunk(&a_Chunk) {} double m_Distance; - cChunk* m_Chunk; + cChunk * m_Chunk; }; struct sMonsterAndChunk { - sMonsterAndChunk(cEntity& a_Monster, cChunk& a_Chunk) : m_Monster(a_Monster), m_Chunk(a_Chunk) {} - cEntity& m_Monster; - cChunk& m_Chunk; + sMonsterAndChunk(cEntity & a_Monster, cChunk & a_Chunk) : m_Monster(a_Monster), m_Chunk(a_Chunk) {} + cEntity & m_Monster; + cChunk & m_Chunk; }; public : - typedef std::map tMonsterToDistance; + typedef std::map tMonsterToDistance; typedef std::multimap tDistanceToMonster; protected : @@ -50,7 +50,7 @@ public : // count a mob on a specified chunk with specified distance to an unkown player // if the distance is shortest than the one collected, this become the new closest // distance and the chunk become the "hosting" chunk (that is the one that will perform the action) - void CollectMob(cEntity& a_Monster, cChunk& a_Chunk, double a_Distance); + void CollectMob(cEntity & a_Monster, cChunk & a_Chunk, double a_Distance); // return the mobs that are within the range of distance of the closest player they are // that means that if a mob is 30 m from a player and 150 m from another one. It will be diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index dfeab1461..468b0cfb2 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -321,9 +321,9 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R -cMonster* cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int& a_MaxPackSize) +cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize) { - cMonster* toReturn = nullptr; + cMonster * toReturn = nullptr; if (m_NewPack) { m_MobType = ChooseMobType(a_Biome); diff --git a/src/MobSpawner.h b/src/MobSpawner.h index e8b8f191b..8b651d6bf 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -39,7 +39,7 @@ public : // if this is the first of a Pack : determine the type of monster // BlockType & BlockMeta are used to decide what kind of Mob can Spawn here // MaxPackSize is set to the maximal size for a pack this type of mob - cMonster * TryToSpawnHere(cChunk * a_Chunk, int A_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int& a_MaxPackSize); + cMonster * TryToSpawnHere(cChunk * a_Chunk, int A_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize); // mark the beginning of a new Pack // all mobs of the same Pack are the same type diff --git a/src/MonsterConfig.h b/src/MonsterConfig.h index 371d324c2..50979c44a 100644 --- a/src/MonsterConfig.h +++ b/src/MonsterConfig.h @@ -23,7 +23,7 @@ public: private: struct sAttributesStruct; struct sMonsterConfigState; - sMonsterConfigState* m_pState; + sMonsterConfigState * m_pState; void Initialize(); } ; diff --git a/src/OSSupport/Semaphore.h b/src/OSSupport/Semaphore.h index adc531ed8..57fa4bdb2 100644 --- a/src/OSSupport/Semaphore.h +++ b/src/OSSupport/Semaphore.h @@ -9,7 +9,7 @@ public: void Wait(); void Signal(); private: - void* m_Handle; // HANDLE pointer + void * m_Handle; // HANDLE pointer #ifndef _WIN32 bool m_bNamed; diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 60fd5f935..2b9c06779 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -68,7 +68,7 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int void cChunkDataSerializer::Serialize29(AString & a_Data) { - // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) + // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib can stream) const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; const int MetadataOffset = sizeof(m_BlockTypes); @@ -126,7 +126,7 @@ void cChunkDataSerializer::Serialize29(AString & a_Data) void cChunkDataSerializer::Serialize39(AString & a_Data) { - // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) + // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib can stream) const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; const int MetadataOffset = sizeof(m_BlockTypes); diff --git a/src/Root.cpp b/src/Root.cpp index 1379b01a2..349608e8d 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -311,8 +311,8 @@ void cRoot::LoadWorlds(cIniFile & IniFile) continue; } FoundAdditionalWorlds = true; - cWorld* NewWorld = new cWorld( WorldName.c_str()); - m_WorldsByName[ WorldName ] = NewWorld; + cWorld * NewWorld = new cWorld(WorldName.c_str()); + m_WorldsByName[WorldName] = NewWorld; } // for i - Worlds if (!FoundAdditionalWorlds) diff --git a/src/Root.h b/src/Root.h index 2f9d1eb2c..e0b6cf26c 100644 --- a/src/Root.h +++ b/src/Root.h @@ -218,7 +218,7 @@ private: /// Does the actual work of executing a command void DoExecuteConsoleCommand(const AString & a_Cmd); - static cRoot* s_Root; + static cRoot * s_Root; static void InputThread(cRoot & a_Params); }; // tolua_export diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index adce8b549..a4a4c3391 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -286,7 +286,7 @@ cScoreboard::cScoreboard(cWorld * a_World) : m_World(a_World) -cObjective* cScoreboard::RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type) +cObjective * cScoreboard::RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type) { cObjective Objective(a_Name, a_DisplayName, a_Type, m_World); @@ -471,7 +471,7 @@ cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot) -bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback) +bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback & a_Callback) { cCSLock Lock(m_CSObjectives); @@ -493,7 +493,7 @@ bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb -bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) +bool cScoreboard::ForEachObjective(cObjectiveCallback & a_Callback) { cCSLock Lock(m_CSObjectives); @@ -512,7 +512,7 @@ bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) -bool cScoreboard::ForEachTeam(cTeamCallback& a_Callback) +bool cScoreboard::ForEachTeam(cTeamCallback & a_Callback) { cCSLock Lock(m_CSTeams); diff --git a/src/Scoreboard.h b/src/Scoreboard.h index dd4073c89..ab10b20aa 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -262,19 +262,16 @@ public: cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) /** Execute callback for each objective with the specified type - Returns true if all objectives processed, false if the callback aborted by returning true. - */ - bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); + Returns true if all objectives processed, false if the callback aborted by returning true. */ + bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback & a_Callback); /** Execute callback for each objective. - Returns true if all objectives have been processed, false if the callback aborted by returning true. - */ - bool ForEachObjective(cObjectiveCallback& a_Callback); // Exported in ManualBindings.cpp + Returns true if all objectives have been processed, false if the callback aborted by returning true. */ + bool ForEachObjective(cObjectiveCallback & a_Callback); // Exported in ManualBindings.cpp /** Execute callback for each team. - Returns true if all teams have been processed, false if the callback aborted by returning true. - */ - bool ForEachTeam(cTeamCallback& a_Callback); // Exported in ManualBindings.cpp + Returns true if all teams have been processed, false if the callback aborted by returning true. */ + bool ForEachTeam(cTeamCallback & a_Callback); // Exported in ManualBindings.cpp void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); diff --git a/src/StringUtils.h b/src/StringUtils.h index 785197763..b5fc58a2d 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -75,7 +75,7 @@ extern int NoCaseCompare(const AString & s1, const AString & s2); // tolua_expo /** Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1.length()]. */ extern size_t RateCompareString(const AString & s1, const AString & s2); -/** Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith */ +/** Replaces each occurence of iNeedle in iHayStack with iReplaceWith */ extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); // tolua_export /** Converts a stream of BE shorts into UTF-8 string; returns a_UTF8. */ diff --git a/src/Tracer.h b/src/Tracer.h index 31531719f..55c21546b 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -64,8 +64,9 @@ private: int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); /// Signum function - int SigNum( float a_Num); - cWorld* m_World; + int SigNum(float a_Num); + + cWorld * m_World; static const std::array & m_NormalTable(void); diff --git a/src/UI/MinecartWithChestWindow.h b/src/UI/MinecartWithChestWindow.h index a2b5283a6..87e8f6137 100644 --- a/src/UI/MinecartWithChestWindow.h +++ b/src/UI/MinecartWithChestWindow.h @@ -33,7 +33,7 @@ public: a_ChestCart->GetWorld()->BroadcastSoundEffect("random.chestopen", a_ChestCart->GetPosX(), a_ChestCart->GetPosY(), a_ChestCart->GetPosZ(), 1, 1); } - virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea* a_ClickedArea, bool a_ShouldApply) override + virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override { cSlotAreas AreasInOrder; diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 484626de3..1cb4463e1 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -531,7 +531,7 @@ AString cWebAdmin::GetDefaultPage(void) -AString cWebAdmin::GetBaseURL( const AString& a_URL) +AString cWebAdmin::GetBaseURL(const AString & a_URL) { return GetBaseURL(StringSplit(a_URL, "/")); } diff --git a/src/World.cpp b/src/World.cpp index d0406f078..648c9cd19 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1351,7 +1351,7 @@ bool cWorld::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc -bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback& a_Callback) +bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) { return m_ChunkMap->DoWithBeaconAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); } diff --git a/src/WorldStorage/EnchantmentSerializer.cpp b/src/WorldStorage/EnchantmentSerializer.cpp index 56072207f..a6e562956 100644 --- a/src/WorldStorage/EnchantmentSerializer.cpp +++ b/src/WorldStorage/EnchantmentSerializer.cpp @@ -5,7 +5,7 @@ #include "Enchantments.h" #include "FastNBT.h" -void EnchantmentSerializer::WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName) +void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName) { // Write the enchantments into the specified NBT writer // begin with the LIST tag of the specified name ("ench" or "StoredEnchantments") @@ -25,7 +25,7 @@ void EnchantmentSerializer::WriteToNBTCompound(cEnchantments const& a_Enchantmen -void EnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx) +void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx) { // Read the enchantments from the specified NBT list tag (ench or StoredEnchantments) diff --git a/src/WorldStorage/EnchantmentSerializer.h b/src/WorldStorage/EnchantmentSerializer.h index 9ed362900..7d6546aad 100644 --- a/src/WorldStorage/EnchantmentSerializer.h +++ b/src/WorldStorage/EnchantmentSerializer.h @@ -9,9 +9,9 @@ namespace EnchantmentSerializer { /// Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") - void WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); + void WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); /// Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) - void ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); + void ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); }; diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 6f0449041..da7b9d929 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -15,8 +15,8 @@ -cMapSerializer::cMapSerializer(const AString& a_WorldName, cMap * a_Map) - : m_Map(a_Map) +cMapSerializer::cMapSerializer(const AString & a_WorldName, cMap * a_Map): + m_Map(a_Map) { AString DataPath; Printf(DataPath, "%s%cdata", a_WorldName.c_str(), cFile::PathSeparator); diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index e13a75c8f..007f1347b 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -26,7 +26,7 @@ class cMapSerializer { public: - cMapSerializer(const AString& a_WorldName, cMap * a_Map); + cMapSerializer(const AString & a_WorldName, cMap * a_Map); /** Try to load the map */ bool Load(void); diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 0d8730e49..01e56dbe1 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -14,13 +14,13 @@ -cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard) - : m_ScoreBoard(a_ScoreBoard) +cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScoreboard * a_ScoreBoard): + m_ScoreBoard(a_ScoreBoard) { AString DataPath; Printf(DataPath, "%s%cdata", a_WorldName.c_str(), cFile::PathSeparator); - m_Path = DataPath + "/scoreboard.dat"; + m_Path = DataPath + cFile::PathSeparator + "scoreboard.dat"; cFile::CreateFolder(FILE_IO_PREFIX + DataPath); } diff --git a/src/WorldStorage/ScoreboardSerializer.h b/src/WorldStorage/ScoreboardSerializer.h index 048fa3ab4..f9065b35f 100644 --- a/src/WorldStorage/ScoreboardSerializer.h +++ b/src/WorldStorage/ScoreboardSerializer.h @@ -25,7 +25,7 @@ class cScoreboardSerializer { public: - cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard); + cScoreboardSerializer(const AString & a_WorldName, cScoreboard * a_ScoreBoard); /// Try to load the scoreboard bool Load(void); @@ -40,7 +40,7 @@ private: bool LoadScoreboardFromNBT(const cParsedNBT & a_NBT); - cScoreboard* m_ScoreBoard; + cScoreboard * m_ScoreBoard; AString m_Path; diff --git a/src/WorldStorage/StatSerializer.h b/src/WorldStorage/StatSerializer.h index 72f8d74f1..6b7efddbb 100644 --- a/src/WorldStorage/StatSerializer.h +++ b/src/WorldStorage/StatSerializer.h @@ -43,7 +43,7 @@ protected: private: - cStatManager* m_Manager; + cStatManager * m_Manager; AString m_Path; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index f389e7cbf..392b9bf83 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -3148,7 +3148,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri } // Store the header: - ChunkSize = ((u_long)a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number + ChunkSize = ((u_long)a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size up to nearest 4KB sector, make it a sector number if (ChunkSize > 255) { LOGWARNING("Cannot save chunk [%d, %d], the data is too large (%u KiB, maximum is 1024 KiB). Remove some entities and retry.", -- cgit v1.2.3 From 756d31031843c3363c991477fa7788b11894d619 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 9 May 2015 11:40:06 +0200 Subject: Added check against "Type const &" and "Type const *". --- src/CheckBasicStyle.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 133446350..9ff47634d 100755 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -178,6 +178,10 @@ local g_ViolationPatterns = {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%&[a-zA-Z0-9]+", "Add space around /"}, {"^[a-zA-Z0-9]+%& [a-zA-Z0-9]+", "Add space before &"}, {"^[^\"]*[!@#$%%%^&*() %[%]\t][a-zA-Z0-9]+%& [a-zA-Z0-9]+", "Add space before &"}, + + -- We don't like "Type const *" and "Type const &". Use "const Type *" and "const Type &" instead: + {"const %&", "Use 'const Type &' instead of 'Type const &'"}, + {"const %*", "Use 'const Type *' instead of 'Type const *'"}, } -- cgit v1.2.3 From 8a576a0a35d0db0cfe510213bfb5ec5af1323777 Mon Sep 17 00:00:00 2001 From: wiseoldman95 Date: Sun, 10 May 2015 09:08:42 +0300 Subject: PF - Less calcs per tick --- src/Mobs/Path.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index 8abbc4cac..ba7d615ae 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -8,7 +8,7 @@ #define DISTANCE_MANHATTAN 0 // 1: More speed, a bit less accuracy 0: Max accuracy, less speed. #define HEURISTICS_ONLY 0 // 1: Much more speed, much less accurate. -#define CALCULATIONS_PER_STEP 60 // Higher means more CPU load but faster path calculations. +#define CALCULATIONS_PER_STEP 5 // Higher means more CPU load but faster path calculations. // The only version which guarantees the shortest path is 0, 0. enum class eCellStatus {OPENLIST, CLOSEDLIST, NOLIST}; -- cgit v1.2.3 From 11ef1fd24a48f8982ecf9c798047b0465ca839a2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 9 May 2015 01:51:25 +0100 Subject: Fixed some warnings and logic errors in Monster.cpp --- src/Mobs/Monster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index dc950ff7d..1cc6e7391 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -1170,17 +1170,19 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn) bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) { - cChunk * Chunk = a_Chunk.GetNeighborChunk(FloorC(m_NextWayPointPosition.x), FloorC(m_NextWayPointPosition.z)); + cChunk * Chunk = a_Chunk.GetNeighborChunk(FloorC(a_Location.x), FloorC(a_Location.z)); if ((Chunk == nullptr) || (!Chunk->IsValid())) { return false; } - int RelX = FloorC(a_Location.x) - a_Chunk.GetPosX() * cChunkDef::Width; + + int RelX = FloorC(a_Location.x) - Chunk->GetPosX() * cChunkDef::Width; int RelY = FloorC(a_Location.y); - int RelZ = FloorC(a_Location.z) - a_Chunk.GetPosZ() * cChunkDef::Width; + int RelZ = FloorC(a_Location.z) - Chunk->GetPosZ() * cChunkDef::Width; + if ( - (a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight - (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand + (Chunk->GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight + (Chunk->GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand (GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining ) -- cgit v1.2.3 From cbb1eff17a085f57472f67cbe3682232fb3a4aeb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 21:29:06 +0200 Subject: Added the EntireCommand parameter to HOOK_EXECUTE_COMMAND. Fixes #1996. --- MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua | 3 ++- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 8 ++++---- src/Bindings/PluginManager.h | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua index dadc4e94f..d7a5d383d 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua @@ -16,7 +16,8 @@ return Params = { { Name = "Player", Type = "{{cPlayer}}", Notes = "For in-game commands, the player who has sent the message. For console commands, nil" }, - { Name = "Command", Type = "table of strings", Notes = "The command and its parameters, broken into a table by spaces" }, + { Name = "CommandSplit", Type = "array-table of strings", Notes = "The command and its parameters, broken into a table by spaces" }, + { Name = "EntireCommand", Type = "string", Notes = "The entire command as a single string" }, }, Returns = [[ If the plugin returns true, the command will be blocked and none of the remaining hook handlers will diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 5c43f9042..6b6a00ba6 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -56,7 +56,7 @@ public: virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; - virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0; + virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 4c98b8d26..4cdc5e667 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -534,7 +534,7 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E -bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split) +bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) { cCSLock Lock(m_CriticalSection); if (!m_LuaState.IsValid()) @@ -545,7 +545,7 @@ bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Sp cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_EXECUTE_COMMAND]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Split, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), a_Player, a_Split, a_EntireCommand, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index bedb3d83b..5c5fabec2 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -115,7 +115,7 @@ public: virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; - virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override; + virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 003996802..ecb0bec45 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -525,14 +525,14 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d & -bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split) +bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) { FIND_HOOK(HOOK_EXECUTE_COMMAND); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnExecuteCommand(a_Player, a_Split)) + if ((*itr)->OnExecuteCommand(a_Player, a_Split, a_EntireCommand)) { return true; } @@ -1449,7 +1449,7 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, } // Ask plugins first if a command is okay to execute the command: - if (CallHookExecuteCommand(&a_Player, Split)) + if (CallHookExecuteCommand(&a_Player, Split, a_Command)) { LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str()); return crBlocked; @@ -1760,7 +1760,7 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma } // Ask plugins first if a command is okay to execute the console command: - if (CallHookExecuteCommand(nullptr, a_Split)) + if (CallHookExecuteCommand(nullptr, a_Split, a_Command)) { a_Output.Out("Command \"%s\" was stopped by the HOOK_EXECUTE_COMMAND hook", a_Split[0].c_str()); return false; diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 994f19943..d72bd50a3 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -200,7 +200,7 @@ public: bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition); - bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == nullptr, it is a console cmd + bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand); // If a_Player == nullptr, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username); -- cgit v1.2.3 From 87f1cf5622eb5fa6d7b6378166c8cc6926aaaa72 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 21:33:49 +0200 Subject: InfoReg: Fixed EntireCommand handling for MultiCommandHandler(). The EntireCommand wasn't propagated into the handlers. --- MCServer/Plugins/InfoReg.lua | 68 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/MCServer/Plugins/InfoReg.lua b/MCServer/Plugins/InfoReg.lua index e34b79564..cc075c0b8 100644 --- a/MCServer/Plugins/InfoReg.lua +++ b/MCServer/Plugins/InfoReg.lua @@ -43,21 +43,21 @@ end --- This is a generic command callback used for handling multicommands' parent commands -- For example, if there are "/gal save" and "/gal load" commands, this callback handles the "/gal" command -- It is used for both console and in-game commands; the console version has a_Player set to nil -local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_Level) - local Verb = a_Split[a_Level + 1]; +local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_Level, a_EntireCommand) + local Verb = a_Split[a_Level + 1] if (Verb == nil) then -- No verb was specified. If there is a handler for the upper level command, call it: if (a_CmdInfo.Handler ~= nil) then - return a_CmdInfo.Handler(a_Split, a_Player); + return a_CmdInfo.Handler(a_Split, a_Player, a_EntireCommand) end -- Let the player know they need to give a subcommand: assert(type(a_CmdInfo.Subcommands) == "table", "Info.lua error: There is no handler for command \"" .. a_CmdString .. "\" and there are no subcommands defined at level " .. a_Level) - ListSubcommands(a_Player, a_CmdInfo.Subcommands, a_CmdString); - return true; + ListSubcommands(a_Player, a_CmdInfo.Subcommands, a_CmdString) + return true end -- A verb was specified, look it up in the subcommands table: - local Subcommand = a_CmdInfo.Subcommands[Verb]; + local Subcommand = a_CmdInfo.Subcommands[Verb] if (Subcommand == nil) then if (a_Level > 1) then -- This is a true subcommand, display the message and make MCS think the command was handled @@ -67,7 +67,7 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ else a_Player:SendMessage("The " .. a_CmdString .. " command doesn't support verb " .. Verb) end - return true; + return true end -- This is a top-level command, let MCS handle the unknown message return false; @@ -76,22 +76,22 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ -- Check the permission: if (a_Player ~= nil) then if not(a_Player:HasPermission(Subcommand.Permission or "")) then - a_Player:SendMessage("You don't have permission to execute this command"); - return true; + a_Player:SendMessage("You don't have permission to execute this command") + return true end end -- If the handler is not valid, check the next sublevel: if (Subcommand.Handler == nil) then if (Subcommand.Subcommands == nil) then - LOG("Cannot find handler for command " .. a_CmdString .. " " .. Verb); - return false; + LOG("Cannot find handler for command " .. a_CmdString .. " " .. Verb) + return false end - return MultiCommandHandler(a_Split, a_Player, a_CmdString .. " " .. Verb, Subcommand, a_Level + 1); + return MultiCommandHandler(a_Split, a_Player, a_CmdString .. " " .. Verb, Subcommand, a_Level + 1, a_EntireCommand) end -- Execute: - return Subcommand.Handler(a_Split, a_Player); + return Subcommand.Handler(a_Split, a_Player, a_EntireCommand) end @@ -104,39 +104,39 @@ function RegisterPluginInfoCommands() -- The a_Prefix param already contains the space after the previous command -- a_Level is the depth of the subcommands being registered, with 1 being the top level command local function RegisterSubcommands(a_Prefix, a_Subcommands, a_Level) - assert(a_Subcommands ~= nil); + assert(a_Subcommands ~= nil) -- A table that will hold aliases to subcommands temporarily, during subcommand iteration local AliasTable = {} -- Iterate through the subcommands, register them, and accumulate aliases: for cmd, info in pairs(a_Subcommands) do - local CmdName = a_Prefix .. cmd; - local Handler = info.Handler; + local CmdName = a_Prefix .. cmd + local Handler = info.Handler -- Provide a special handler for multicommands: if (info.Subcommands ~= nil) then - Handler = function(a_Split, a_Player) - return MultiCommandHandler(a_Split, a_Player, CmdName, info, a_Level); + Handler = function(a_Split, a_Player, a_EntireCommand) + return MultiCommandHandler(a_Split, a_Player, CmdName, info, a_Level, a_EntireCommand) end end if (Handler == nil) then - LOGWARNING(g_PluginInfo.Name .. ": Invalid handler for command " .. CmdName .. ", command will not be registered."); + LOGWARNING(g_PluginInfo.Name .. ": Invalid handler for command " .. CmdName .. ", command will not be registered.") else - local HelpString; + local HelpString if (info.HelpString ~= nil) then - HelpString = " - " .. info.HelpString; + HelpString = " - " .. info.HelpString else - HelpString = ""; + HelpString = "" end - cPluginManager.BindCommand(CmdName, info.Permission or "", Handler, HelpString); + cPluginManager.BindCommand(CmdName, info.Permission or "", Handler, HelpString) -- Register all aliases for the command: if (info.Alias ~= nil) then if (type(info.Alias) == "string") then - info.Alias = {info.Alias}; + info.Alias = {info.Alias} end for idx, alias in ipairs(info.Alias) do - cPluginManager.BindCommand(a_Prefix .. alias, info.Permission or "", Handler, HelpString); + cPluginManager.BindCommand(a_Prefix .. alias, info.Permission or "", Handler, HelpString) -- Also copy the alias's info table as a separate subcommand, -- so that MultiCommandHandler() handles it properly. Need to off-load into a separate table -- than the one we're currently iterating and join after the iterating. @@ -147,7 +147,7 @@ function RegisterPluginInfoCommands() -- Recursively register any subcommands: if (info.Subcommands ~= nil) then - RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1); + RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1) end end -- for cmd, info - a_Subcommands[] @@ -159,7 +159,7 @@ function RegisterPluginInfoCommands() end -- Loop through all commands in the plugin info, register each: - RegisterSubcommands("", g_PluginInfo.Commands, 1); + RegisterSubcommands("", g_PluginInfo.Commands, 1) end @@ -171,26 +171,26 @@ function RegisterPluginInfoConsoleCommands() -- A sub-function that registers all subcommands of a single command, using the command's Subcommands table -- The a_Prefix param already contains the space after the previous command local function RegisterSubcommands(a_Prefix, a_Subcommands, a_Level) - assert(a_Subcommands ~= nil); + assert(a_Subcommands ~= nil) for cmd, info in pairs(a_Subcommands) do - local CmdName = a_Prefix .. cmd; + local CmdName = a_Prefix .. cmd local Handler = info.Handler if (Handler == nil) then - Handler = function(a_Split) - return MultiCommandHandler(a_Split, nil, CmdName, info, a_Level); + Handler = function(a_Split, a_EntireCommand) + return MultiCommandHandler(a_Split, nil, CmdName, info, a_Level, a_EntireCommand) end end - cPluginManager.BindConsoleCommand(CmdName, Handler, info.HelpString or ""); + cPluginManager.BindConsoleCommand(CmdName, Handler, info.HelpString or "") -- Recursively register any subcommands: if (info.Subcommands ~= nil) then - RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1); + RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1) end end end -- Loop through all commands in the plugin info, register each: - RegisterSubcommands("", g_PluginInfo.ConsoleCommands, 1); + RegisterSubcommands("", g_PluginInfo.ConsoleCommands, 1) end -- cgit v1.2.3 From b356419a072076eb1ceae3dd73f6391ce5519460 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 21:34:31 +0200 Subject: StringUtils: Fixed StringSplitWithQuotes(). The function would crash when given a string that started with the delimiter. --- src/StringUtils.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 4adc6a0a0..12bd3ada1 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -150,6 +150,13 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) { + if (cutAt == Prev) + { + // Empty string due to multiple whitespace / whitespace at the beginning of the input + // Just skip it + Prev = Prev + 1; + continue; + } AString current = str.substr(Prev, cutAt - Prev); if ((current.front() == '"') || (current.front() == '\'')) { -- cgit v1.2.3 From 6c53abed23011423e95a30d2ad50bbe95aca365e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 21:46:25 +0200 Subject: Call HOOK_EXECUTE_COMMAND even for unknown console commands. This allows plugins such as Aliases to intercept even unknown commands. --- MCServer/Plugins/APIDump/Hooks/OnChat.lua | 3 ++- MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua | 12 ++++++++++-- src/Bindings/PluginManager.cpp | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnChat.lua b/MCServer/Plugins/APIDump/Hooks/OnChat.lua index d98df008a..a15d09cc7 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnChat.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnChat.lua @@ -7,7 +7,8 @@ return Desc = [[ A plugin may implement an OnChat() function and register it as a Hook to process chat messages from the players. The function is then called for every in-game message sent from any player. Note that - commands are handled separately using a command framework API. + registered in-game commands are not sent through this hook. Use the + {{OnExecuteCommand|HOOK_EXECUTE_COMMAND}} to intercept registered in-game commands. ]], Params = { { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who sent the message" }, diff --git a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua index d7a5d383d..d920a83ba 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua @@ -2,7 +2,10 @@ return { HOOK_EXECUTE_COMMAND = { - CalledWhen = "A player executes an in-game command, or the admin issues a console command. Note that built-in console commands are exempt to this hook - they are always performed and the hook is not called.", + CalledWhen = [[ + A player executes an in-game command, or the admin issues a console command. Note that built-in + console commands are exempt to this hook - they are always performed and the hook is not called. + ]], DefaultFnName = "OnExecuteCommand", -- also used as pagename Desc = [[ A plugin may implement a callback for this hook to intercept both in-game commands executed by the @@ -11,7 +14,12 @@ return server.

If the command is in-game, the first parameter to the hook function is the {{cPlayer|player}} who's - executing the command. If the command comes from the server console, the first parameter is nil. + executing the command. If the command comes from the server console, the first parameter is nil.

+

+ The server calls this hook even for unregistered (unknown) console commands. However, it doesn't call + the hook for unregistered in-game commands, simply because there's no way to distinguish between a + command and a chat message. If a plugin needs to intercept unknown in-game commands, it should use the + {{OnChat|HOOK_CHAT}} hook. ]], Params = { diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index ecb0bec45..7384f43bd 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1750,6 +1750,8 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma if (cmd == m_ConsoleCommands.end()) { // Command not found + // Still notify the plugins (so that plugins such as Aliases can intercept unknown commands): + CallHookExecuteCommand(nullptr, a_Split, a_Command); return false; } -- cgit v1.2.3 From 693ffb689c1b970e97cca1bb7d3982695e277eca Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 22:51:16 +0200 Subject: Exported cPluginManager:ExecuteConsoleCommand() to Lua API. Fixes #1999. --- MCServer/Plugins/APIDump/Classes/Plugins.lua | 1 + src/Bindings/ManualBindings.cpp | 39 +++++++++++++++++++++++++++- src/Bindings/PluginManager.h | 4 ++- src/CommandOutput.cpp | 19 ++++++++------ src/CommandOutput.h | 30 ++++++++++++++++----- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/MCServer/Plugins/APIDump/Classes/Plugins.lua b/MCServer/Plugins/APIDump/Classes/Plugins.lua index ff5d4a180..87f864950 100644 --- a/MCServer/Plugins/APIDump/Classes/Plugins.lua +++ b/MCServer/Plugins/APIDump/Classes/Plugins.lua @@ -68,6 +68,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." }, DoWithPlugin = { Params = "PluginName, CallbackFn", Return = "bool", Notes = "(STATIC) Calls the CallbackFn for the specified plugin, if found. A plugin can be found even if it is currently unloaded, disabled or errored, the callback should check the plugin status. If the plugin is not found, this function returns false, otherwise it returns the bool value that the callback has returned. The CallbackFn has the following signature:

function ({{cPlugin|Plugin}})
" }, ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions." }, + ExecuteConsoleCommand = { Params = "CommandStr", Return = "bool, string", Notes = "Executes the console command as if given by the admin on the console. If the command is successfully executed, returns true and the text that would be output to the console normally. On error it returns false and an error message." }, FindPlugins = { Params = "", Return = "", Notes = "OBSOLETE, use RefreshPluginList() instead"}, ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" }, ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature:
function(Command, Permission, HelpString)
If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9b3c1555d..bfe280f51 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -5,6 +5,7 @@ #undef TOLUA_TEMPLATE_BIND #include #include +#include #include "tolua++/include/tolua++.h" #include "polarssl/md5.h" #include "polarssl/sha1.h" @@ -33,9 +34,10 @@ #include "../CompositeChat.h" #include "../StringCompression.h" #include "../Broadcaster.h" +#include "../CommandOutput.h" + -#include // Better error reporting for Lua @@ -2000,6 +2002,40 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) +static int tolua_cPluginManager_ExecuteConsoleCommand(lua_State * tolua_S) +{ + /* + Function signature: + cPluginManager:ExecuteConsoleCommand(EntireCommandStr) -> OutputString + */ + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cPluginManager") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString Command; + L.GetStackValues(2, Command); + auto Split = StringSplit(Command, " "); + + // Store the command output in a string: + cStringAccumCommandOutputCallback CommandOutput; + L.Push(cPluginManager::Get()->ExecuteConsoleCommand(Split, CommandOutput, Command)); + L.Push(CommandOutput.GetAccum()); + return 2; +} + + + + + static int tolua_cPluginManager_FindPlugins(lua_State * tolua_S) { // API function no longer exists: @@ -3906,6 +3942,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "BindConsoleCommand", tolua_cPluginManager_BindConsoleCommand); tolua_function(tolua_S, "CallPlugin", tolua_cPluginManager_CallPlugin); tolua_function(tolua_S, "DoWithPlugin", tolua_StaticDoWith); + tolua_function(tolua_S, "ExecuteConsoleCommand", tolua_cPluginManager_ExecuteConsoleCommand); tolua_function(tolua_S, "FindPlugins", tolua_cPluginManager_FindPlugins); tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand); tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index d72bd50a3..6fad98434 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -299,7 +299,9 @@ public: /** Returns true if the console command is in the command map */ bool IsConsoleCommandBound(const AString & a_Command); // tolua_export - /** Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback */ + /** Executes the command split into a_Split, as if it was given on the console. + Returns true if executed. Output is sent to the a_Output callback + Exported in ManualBindings.cpp with a different signature. */ bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_Command); /** Appends all commands beginning with a_Text (case-insensitive) into a_Results. diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 510461d81..255ec3e9b 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -29,29 +29,32 @@ void cCommandOutputCallback::Out(const char * a_Fmt, ...) //////////////////////////////////////////////////////////////////////////////// -// cLogCommandOutputCallback: +// cStringAccumCommandOutputCallback: -void cLogCommandOutputCallback::Out(const AString & a_Text) +void cStringAccumCommandOutputCallback::Out(const AString & a_Text) { - m_Buffer.append(a_Text); + m_Accum.append(a_Text); } +//////////////////////////////////////////////////////////////////////////////// +// cLogCommandOutputCallback: + void cLogCommandOutputCallback::Finished(void) { // Log each line separately: - size_t len = m_Buffer.length(); + size_t len = m_Accum.length(); size_t last = 0; for (size_t i = 0; i < len; i++) { - switch (m_Buffer[i]) + switch (m_Accum[i]) { case '\n': { - LOG("%s", m_Buffer.substr(last, i - last).c_str()); + LOG("%s", m_Accum.substr(last, i - last).c_str()); last = i + 1; break; } @@ -59,11 +62,11 @@ void cLogCommandOutputCallback::Finished(void) } // for i - m_Buffer[] if (last < len) { - LOG("%s", m_Buffer.substr(last).c_str()); + LOG("%s", m_Accum.substr(last).c_str()); } // Clear the buffer for the next command output: - m_Buffer.clear(); + m_Accum.clear(); } diff --git a/src/CommandOutput.h b/src/CommandOutput.h index daa9430c0..6265b74ea 100644 --- a/src/CommandOutput.h +++ b/src/CommandOutput.h @@ -47,18 +47,36 @@ class cNullCommandOutputCallback : -/// Sends all command output to a log, line by line, when the command finishes processing -class cLogCommandOutputCallback : +/** Accumulates all command output into a string. */ +class cStringAccumCommandOutputCallback: public cCommandOutputCallback { + typedef cCommandOutputCallback super; + public: // cCommandOutputCallback overrides: virtual void Out(const AString & a_Text) override; - virtual void Finished(void) override; - + virtual void Finished(void) override {} + + /** Returns the accumulated command output in a string. */ + const AString & GetAccum(void) const { return m_Accum; } + protected: - /// Output is stored here until the command finishes processing - AString m_Buffer; + /** Output is stored here until the command finishes processing */ + AString m_Accum; +} ; + + + + + +/// Sends all command output to a log, line by line, when the command finishes processing +class cLogCommandOutputCallback : + public cStringAccumCommandOutputCallback +{ +public: + // cStringAccumCommandOutputCallback overrides: + virtual void Finished(void) override; } ; -- cgit v1.2.3 From dd10ffb63ad98cf2f4df2141a8fd64c21d414529 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 23:11:30 +0200 Subject: OnExecuteCommand hook can override the command result (crXXX). --- .../Plugins/APIDump/Hooks/OnExecuteCommand.lua | 8 ++++--- src/Bindings/LuaState.cpp | 12 ++++++++++ src/Bindings/LuaState.h | 3 ++- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 27 +++++++++++++--------- src/Bindings/PluginManager.h | 2 +- 8 files changed, 40 insertions(+), 20 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua index d920a83ba..79b7bb055 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua @@ -28,9 +28,11 @@ return { Name = "EntireCommand", Type = "string", Notes = "The entire command as a single string" }, }, Returns = [[ - If the plugin returns true, the command will be blocked and none of the remaining hook handlers will - be called. If the plugin returns false, MCServer calls all the remaining hook handlers and finally - the command will be executed. + If the plugin returns false, MCServer calls all the remaining hook handlers and finally the command + will be executed. If the plugin returns true, the none of the remaining hook handlers will be called. + In this case the plugin can return a second value, specifying whether what the command result should + be set to, one of the {{cPluginManager#CommandResult|CommandResult}} constants. If not + provided, the value defaults to crBlocked. ]], }, -- HOOK_EXECUTE_COMMAND } diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index c96ab083a..fb02569c9 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -958,6 +958,18 @@ void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result) +{ + if (lua_isnumber(m_LuaState, a_StackPos)) + { + a_Result = static_cast(static_cast((tolua_tonumber(m_LuaState, a_StackPos, a_Result)))); + } +} + + + + + void cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref) { a_Ref.RefStack(*this, a_StackPos); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 4377ed5d0..959a62bb8 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -32,6 +32,7 @@ extern "C" #include "../Vector3.h" #include "../Defines.h" +#include "PluginManager.h" @@ -57,7 +58,6 @@ class cPickup; class cPlayer; class cPlugin; class cPluginLua; -class cPluginManager; class cProjectileEntity; class cRoot; class cScoreboard; @@ -249,6 +249,7 @@ public: void GetStackValue(int a_StackPos, AString & a_Value); void GetStackValue(int a_StackPos, BLOCKTYPE & a_Value); void GetStackValue(int a_StackPos, bool & a_Value); + void GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result); void GetStackValue(int a_StackPos, cRef & a_Ref); void GetStackValue(int a_StackPos, double & a_Value); void GetStackValue(int a_StackPos, float & a_ReturnedVal); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 6b6a00ba6..d0c2bcefa 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -56,7 +56,7 @@ public: virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; - virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) = 0; + virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 4cdc5e667..76d3557a4 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -534,7 +534,7 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E -bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) +bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) { cCSLock Lock(m_CriticalSection); if (!m_LuaState.IsValid()) @@ -545,7 +545,7 @@ bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Sp cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_EXECUTE_COMMAND]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Split, a_EntireCommand, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), a_Player, a_Split, a_EntireCommand, cLuaState::Return, res, a_Result); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 5c5fabec2..524c249b0 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -115,7 +115,7 @@ public: virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; - virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) override; + virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 7384f43bd..15bea22bd 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -525,14 +525,14 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d & -bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) +bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result) { FIND_HOOK(HOOK_EXECUTE_COMMAND); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnExecuteCommand(a_Player, a_Split, a_EntireCommand)) + if ((*itr)->OnExecuteCommand(a_Player, a_Split, a_EntireCommand, a_Result)) { return true; } @@ -1449,10 +1449,14 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, } // Ask plugins first if a command is okay to execute the command: - if (CallHookExecuteCommand(&a_Player, Split, a_Command)) + CommandResult Result = crBlocked; + if (CallHookExecuteCommand(&a_Player, Split, a_Command, Result)) { - LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str()); - return crBlocked; + if (Result == crBlocked) + { + LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str()); + } + return Result; } if ( @@ -1750,9 +1754,10 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma if (cmd == m_ConsoleCommands.end()) { // Command not found - // Still notify the plugins (so that plugins such as Aliases can intercept unknown commands): - CallHookExecuteCommand(nullptr, a_Split, a_Command); - return false; + // Still notify the plugins (so that plugins such as Aliases can intercept unknown commands). + CommandResult res = crBlocked; + CallHookExecuteCommand(nullptr, a_Split, a_Command, res); + return (res == crExecuted); } if (cmd->second.m_Plugin == nullptr) @@ -1762,10 +1767,10 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma } // Ask plugins first if a command is okay to execute the console command: - if (CallHookExecuteCommand(nullptr, a_Split, a_Command)) + CommandResult res = crBlocked; + if (CallHookExecuteCommand(nullptr, a_Split, a_Command, res)) { - a_Output.Out("Command \"%s\" was stopped by the HOOK_EXECUTE_COMMAND hook", a_Split[0].c_str()); - return false; + return (res == crExecuted); } return cmd->second.m_Plugin->HandleConsoleCommand(a_Split, a_Output, a_Command); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 6fad98434..d8c886b62 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -200,7 +200,7 @@ public: bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition); - bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand); // If a_Player == nullptr, it is a console cmd + bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result); // If a_Player == nullptr, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username); -- cgit v1.2.3 From 66945e4847bed70dc4a8d724292753b79d4231a9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 23:14:25 +0200 Subject: APIDump: Added linkification to hook return values. --- MCServer/Plugins/APIDump/main_APIDump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 013ec7bef..4ca06b974 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -285,7 +285,7 @@ local function WriteHtmlHook(a_Hook, a_HookNav) for _, param in ipairs(a_Hook.Params) do f:write("", param.Name, "", LinkifyString(param.Type, HookName), "", LinkifyString(param.Notes, HookName), "\n"); end - f:write("\n

" .. (a_Hook.Returns or "") .. "

\n\n"); + f:write("\n

" .. LinkifyString(a_Hook.Returns or "", HookName) .. "

\n\n"); f:write([[

Code examples

Registering the callback

]]); f:write("
\n");
 	f:write([[cPluginManager:AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);]]);
-- 
cgit v1.2.3


From 4083bc70052e8883d38a94dcd9415ed7ed271fde Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Mon, 11 May 2015 16:11:53 +0200
Subject: AllToLua: Removed unneeded virtual method hooks.

---
 src/Bindings/virtual_method_hooks.lua | 488 +---------------------------------
 1 file changed, 7 insertions(+), 481 deletions(-)

diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua
index a52728ff8..14b0bcae5 100644
--- a/src/Bindings/virtual_method_hooks.lua
+++ b/src/Bindings/virtual_method_hooks.lua
@@ -1,7 +1,7 @@
--- flags
-local disable_virtual_hooks = true
-local enable_pure_virtual = true
-local default_private_access = false
+
+-- virtual_method_hooks.lua
+
+-- Implements additional processing that is done while generating the Lua bindings
 
 
 
@@ -9,29 +9,16 @@ local default_private_access = false
 
 local access = {public = 0, protected = 1, private = 2}
 
-function preparse_hook(p)
 
-	if default_private_access then
-		-- we need to make all structs 'public' by default
-		p.code = string.gsub(p.code, "(struct[^;]*{)", "%1\npublic:\n")
-	end
-end
 
 
-function parser_hook(s)
 
+function parser_hook(s)
 	local container = classContainer.curr -- get the current container
 
-	if default_private_access then
-		if not container.curr_member_access and container.classtype == 'class' then
-			-- default access for classes is private
-			container.curr_member_access = access.private
-		end
-	end
-
-	-- try labels (public, private, etc)
+	-- process access-specifying labels (public, private, etc)
 	do
-		local b,e,label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
+		local b, e, label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
 		if b then
 
 			-- found a label, get the new access value from the global 'access' table
@@ -42,469 +29,8 @@ function parser_hook(s)
 			return strsub(s, e) -- normally we would use 'e+1', but we need to preserve the [^:]
 		end
 	end
-
-
-	local ret = nil
-
-	if disable_virtual_hooks then
-
-		return ret
-	end
-
-	local b,e,decl,arg = string.find(s, "^%s*virtual%s+([^%({~]+)(%b())")
-	local const
-	if b then
-		local ret = string.sub(s, e+1)
-		if string.find(ret, "^%s*const") then
-			const = "const"
-			ret = string.gsub(ret, "^%s*const", "")
-		end
-		local purev = false
-		if string.find(ret, "^%s*=%s*0") then
-			purev = true
-			ret = string.gsub(ret, "^%s*=%s*0", "")
-		end
-		ret = string.gsub(ret, "^%s*%b{}", "")
-
-		local func = Function(decl, arg, const)
-		func.pure_virtual = purev
-		--func.access = access
-		func.original_sig = decl
-
-		local curflags = classContainer.curr.flags
-		if not curflags.virtual_class then
-
-			curflags.virtual_class = VirtualClass()
-		end
-		curflags.virtual_class:add(func)
-		curflags.pure_virtual = curflags.pure_virtual or purev
-
-		return ret
-	end
-
-	return ret
-end
-
-
--- class VirtualClass
-classVirtualClass = {
- classtype = 'class',
- name = '',
- base = '',
- type = '',
- btype = '',
- ctype = '',
-}
-classVirtualClass.__index = classVirtualClass
-setmetatable(classVirtualClass,classClass)
-
-function classVirtualClass:add(f)
-
-	local parent = classContainer.curr
-	pop()
-
-	table.insert(self.methods, {f=f})
-
-	local name,sig
-
-	-- doble negative means positive
-	if f.name == 'new' and ((not self.flags.parent_object.flags.pure_virtual) or (enable_pure_virtual)) then
-
-		name = self.original_name
-	elseif f.name == 'delete' then
-		name = '~'..self.original_name
-	else
-		if f.access ~= 2 and (not f.pure_virtual) and f.name ~= 'new' and f.name ~= 'delete' then
-			name = f.mod.." "..f.type..f.ptr.." "..self.flags.parent_object.lname.."__"..f.name
-		end
-	end
-
-	if name then
-		sig = name..self:get_arg_list(f, true)..";\n"
-		push(self)
-		sig = preprocess(sig)
-		self:parse(sig)
-		pop()
-	end
-
-	push(parent)
 end
 
-function preprocess(sig)
-
-	sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
-	sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
-	sig = gsub(sig,"([^%w_])char%s*%*","%1_cstring ")  -- substitute 'char*'
-	sig = gsub(sig,"([^%w_])lua_State%s*%*","%1_lstate ")  -- substitute 'lua_State*'
-
-	return sig
-end
-
-function classVirtualClass:get_arg_list(f, decl)
-
-	local ret = ""
-	local sep = ""
-	local i=1
-	while f.args[i] do
-
-		local arg = f.args[i]
-		if decl then
-			local ptr
-			if arg.ret ~= '' then
-				ptr = arg.ret
-			else
-				ptr = arg.ptr
-			end
-			local def = ""
-			if arg.def and arg.def ~= "" then
-
-				def = " = "..arg.def
-			end
-			ret = ret..sep..arg.mod.." "..arg.type..ptr.." "..arg.name..def
-		else
-			ret = ret..sep..arg.name
-		end
-
-		sep = ","
-		i = i+1
-	end
-
-	return "("..ret..")"
-end
-
-function classVirtualClass:add_parent_virtual_methods(parent)
-
-	parent = parent or _global_classes[self.flags.parent_object.btype]
-
-	if not parent then return end
-
-	if parent.flags.virtual_class then
-
-		local vclass = parent.flags.virtual_class
-		for k,v in ipairs(vclass.methods) do
-			if v.f.name ~= 'new' and v.f.name ~= 'delete' and (not self:has_method(v.f)) then
-				table.insert(self.methods, {f=v.f})
-			end
-		end
-	end
-
-	parent = _global_classes[parent.btype]
-	if parent then
-		self:add_parent_virtual_methods(parent)
-	end
-end
-
-function classVirtualClass:has_method(f)
-
-	for k,v in pairs(self.methods) do
-		-- just match name for now
-		if v.f.name == f.name then
-			return true
-		end
-	end
-
-	return false
-end
-
-function classVirtualClass:add_constructors()
-
-	local i=1
-	while self.flags.parent_object[i] do
-
-		local v = self.flags.parent_object[i]
-		if getmetatable(v) == classFunction and (v.name == 'new' or v.name == 'delete') then
-
-			self:add(v)
-		end
-
-		i = i+1
-	end
-
-end
-
---[[
-function classVirtualClass:requirecollection(t)
-
-	self:add_constructors()
-	local req = classClass.requirecollection(self, t)
-	if req then
-		output('class ',self.name,";")
-	end
-	return req
-end
---]]
-
-function classVirtualClass:supcode()
-
-	-- pure virtual classes can have no default constructors on gcc 4
-
-	if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
-		output('#if (__GNUC__ == 4) || (__GNUC__ > 4 ) // I hope this works on Microsoft Visual studio .net server 2003 XP Compiler\n')
-	end
-
-	local ns
-	if self.prox.classtype == 'namespace' then
-		output('namespace ',self.prox.name, " {")
-		ns = true
-	end
-
-	output("class "..self.original_name.." : public "..self.btype..", public ToluaBase {")
-
-	output("public:\n")
-
-	self:add_parent_virtual_methods()
-
-	self:output_methods(self.btype)
-	self:output_parent_methods()
-
-	self:add_constructors()
-
-	-- no constructor for pure virtual classes
-	if (not self.flags.parent_object.flags.pure_virtual) or enable_pure_virtual then
-
-		self:output_constructors()
-	end
-
-	output("};\n\n")
-
-	if ns then
-		output("};")
-	end
-
-	classClass.supcode(self)
-
-	if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
-		output('#endif // __GNUC__ >= 4\n')
-	end
-
-	-- output collector for custom class if required
-	if self:requirecollection(_collect) and _collect[self.type] then
-
-		output('\n')
-		output('/* function to release collected object via destructor */')
-		output('#ifdef __cplusplus\n')
-		--for i,v in pairs(collect) do
-		i,v = self.type, _collect[self.type]
-		 output('\nstatic int '..v..' (lua_State* tolua_S)')
-			output('{')
-			output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
-			output('	delete self;')
-			output('	return 0;')
-			output('}')
-		--end
-		output('#endif\n\n')
-	end
-
-end
-
-function classVirtualClass:register(pre)
-
-	-- pure virtual classes can have no default constructors on gcc 4
-	if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
-		output('#if (__GNUC__ == 4) || (__GNUC__ > 4 )\n')
-	end
-
-	classClass.register(self, pre)
-
-	if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
-		output('#endif // __GNUC__ >= 4\n')
-	end
-end
-
-
---function classVirtualClass:requirecollection(_c)
---	if self.flags.parent_object.flags.pure_virtual then
---		return false
---	end
---	return classClass.requirecollection(self, _c)
---end
-
-function classVirtualClass:output_parent_methods()
-
-	for k,v in ipairs(self.methods) do
-
-		if v.f.access ~= 2 and (not v.f.pure_virtual) and v.f.name ~= 'new' and v.f.name ~= 'delete' then
-
-			local rettype = v.f.mod.." "..v.f.type..v.f.ptr.." "
-			local parent_name = rettype..self.btype.."__"..v.f.name
-
-			local par_list = self:get_arg_list(v.f, true)
-			local var_list = self:get_arg_list(v.f, false)
-
-			-- the parent's virtual function
-			output("\t"..parent_name..par_list.." {")
-
-			output("\t\treturn (",rettype,")"..self.btype.."::"..v.f.name..var_list..";")
-			output("\t};")
-		end
-	end
-end
-
-function classVirtualClass:output_methods(btype)
-
-	for k,v in ipairs(self.methods) do
-
-		if v.f.name ~= 'new' and v.f.name ~= 'delete' then
-
-			self:output_method(v.f, btype)
-		end
-	end
-	output("\n")
-end
-
-function classVirtualClass:output_constructors()
-
-	for k,v in ipairs(self.methods) do
-
-		if v.f.name == 'new' then
-
-			local par_list = self:get_arg_list(v.f, true)
-			local var_list = self:get_arg_list(v.f, false)
-
-			output("\t",self.original_name,par_list,":",self.btype,var_list,"{};")
-		end
-	end
-end
-
-function classVirtualClass:output_method(f, btype)
-
-	if f.access == 2 then -- private
-		return
-	end
-
-	local ptr
-	if f.ret ~= '' then
-		ptr = f.ret
-	else
-		ptr = f.ptr
-	end
-
-	local rettype = f.mod.." "..f.type..f.ptr.." "
-	local par_list = self:get_arg_list(f, true)
-	local var_list = self:get_arg_list(f, false)
-
-	if string.find(rettype, "%s*LuaQtGenericFlags%s*") then
-
-		_,_,rettype = string.find(f.original_sig, "^%s*([^%s]+)%s+")
-	end
-
-	-- the caller of the lua method
-	output("\t"..rettype.." "..f.name..par_list..f.const.." {")
-	local fn = f.cname
-	if f.access == 1 then
-		fn = "NULL"
-	end
-	output('\t\tif (push_method("',f.lname,'", ',fn,')) {')
-
-	--if f.type ~= 'void' then
-	--	output("\t\t\tint top = lua_gettop(lua_state)-1;")
-	--end
-
-	-- push the parameters
-	local argn = 0
-	for i,arg in ipairs(f.args) do
-		if arg.type ~= 'void' then
-			local t,ct = isbasic(arg.type)
-			if t and t ~= '' then
-				if arg.ret == "*" then
-					t = 'userdata'
-					ct = 'void*'
-				end
-				output("\t\t\ttolua_push"..t.."(lua_state, ("..ct..")"..arg.name..");");
-			else
-				local m = arg.ptr
-				if m and m~= "" then
-					if m == "*" then m = "" end
-					output("\t\t\ttolua_pushusertype(lua_state, (void*)"..m..arg.name..", \""..arg.type.."\");")
-				else
-					output("\t\t\tvoid* tolua_obj" .. argn .." = (void*)new "..arg.type.."("..arg.name..");\n")
-					output('\t\t\ttolua_pushusertype_and_takeownership(lua_state, tolua_obj' .. argn .. ', "'..arg.type..'");\n')
-				end
-			end
-			argn = argn+1
-		end
-	end
-
-	-- call the function
-	output("\t\t\tToluaBase::dbcall(lua_state, ",argn+1,", ")
-
-	-- return value
-	if f.type ~= 'void' then
-		output("1);")
-
-		local t,ct = isbasic(f.type)
-		if t and t ~= '' then
-			--output("\t\t\treturn ("..rettype..")tolua_to"..t.."(lua_state, top, 0);")
-			output("\t\t\t",rettype,"tolua_ret = ("..rettype..")tolua_to"..t.."(lua_state, -1, 0);")
-		else
-
-			local mod = ""
-			if f.ptr ~= "*" then
-				mod = "*("..f.type.."*)"
-			end
-
-			--output("\t\t\treturn ("..rettype..")"..mod.."tolua_tousertype(lua_state, top, 0);")
-			output("\t\t\t",rettype,"tolua_ret = ("..rettype..")"..mod.."tolua_tousertype(lua_state, -1, 0);")
-		end
-		output("\t\t\tlua_pop(lua_state, 1);")
-		output("\t\t\treturn tolua_ret;")
-	else
-		output("0);")
-	end
-
-	-- handle non-implemeted function
-	output("\t\t} else {")
-
-	if f.pure_virtual then
-
-		output('\t\t\tif (lua_state)')
-		--output('\t\t\t\ttolua_error(lua_state, "pure-virtual method '..btype.."::"..f.name..' not implemented.", NULL);')
-		output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' not implemented.");')
-		output('\t\t\telse {')
-		output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' called with no lua_state. Aborting");')
-		output('\t\t\t\t::abort();')
-		output('\t\t\t};')
-		if( rettype == " std::string " ) then
-			output('\t\t\treturn "";')
-		else
-			output('\t\t\treturn (',rettype,')0;')
-		end
-	else
-
-		output('\t\t\treturn (',rettype,')',btype,'::',f.name,var_list,';')
-	end
-
-	output("\t\t};")
-
-	output("\t};")
-end
-
-function VirtualClass()
-
-	local parent = classContainer.curr
-	pop()
-
-	local name = "Lua__"..parent.original_name
-
-	local c = _Class(_Container{name=name, base=parent.name, extra_bases=nil})
-	setmetatable(c, classVirtualClass)
-
-	local ft = getnamespace(c.parent)..c.original_name
-	append_global_type(ft, c)
-
-	push(parent)
-
-	c.flags.parent_object = parent
-	c.methods = {}
-
-	push(c)
-	c:parse("\nvoid tolua__set_instance(_lstate L, lua_Object lo);\n")
-	pop()
-
-	return c
-end
-
-
 
 
 
-- 
cgit v1.2.3


From 3ddd2f567cfa8ee44c115a8f9449b0ffb5af32ea Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Mon, 11 May 2015 16:19:01 +0200
Subject: ToLua: Fixed LuaJit compatibility.

---
 lib/tolua++/src/bin/lua/compat-5.1.lua | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/tolua++/src/bin/lua/compat-5.1.lua b/lib/tolua++/src/bin/lua/compat-5.1.lua
index c591592a6..c0a3ec388 100644
--- a/lib/tolua++/src/bin/lua/compat-5.1.lua
+++ b/lib/tolua++/src/bin/lua/compat-5.1.lua
@@ -54,3 +54,11 @@ string.repl = ogsub
 
 
 
+-- Lua 5.2+ and LuaJit don't have string.gfind(). Use string.gmatch() instead:
+if not(string.gfind) then
+	string.gfind = string.gmatch
+end
+
+
+
+
-- 
cgit v1.2.3


From 30b17bcb97aaa0c5fcf88ef058b80b9466425442 Mon Sep 17 00:00:00 2001
From: Tiger Wang 
Date: Mon, 11 May 2015 22:58:27 +0100
Subject: Improved hoppers

* Fixes #1994
---
 src/BlockEntities/HopperEntity.cpp | 41 ++++++++++++++------------------------
 src/BlockEntities/HopperEntity.h   |  2 +-
 2 files changed, 16 insertions(+), 27 deletions(-)

diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index bfd4b8322..203f47534 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -430,7 +430,7 @@ bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
 	}
 
 	// Try move from the output slot:
-	if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true))
+	if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput))
 	{
 		cItem NewOutput(Furnace->GetOutputSlot());
 		Furnace->SetOutputSlot(NewOutput.AddCount(-1));
@@ -440,7 +440,7 @@ bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
 	// No output moved, check if we can move an empty bucket out of the fuel slot:
 	if (Furnace->GetFuelSlot().m_ItemType == E_ITEM_BUCKET)
 	{
-		if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsFuel, true))
+		if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsFuel))
 		{
 			Furnace->SetFuelSlot(cItem());
 			return true;
@@ -460,28 +460,13 @@ bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity)
 	cItemGrid & Grid = a_Entity.GetContents();
 	int NumSlots = Grid.GetNumSlots();
 
-	// First try adding items of types already in the hopper:
 	for (int i = 0; i < NumSlots; i++)
 	{
 		if (Grid.IsSlotEmpty(i))
 		{
 			continue;
 		}
-		if (MoveItemsFromSlot(a_Entity, i, false))
-		{
-			Grid.ChangeSlotCount(i, -1);
-			return true;
-		}
-	}
-
-	// No already existing stack can be topped up, try again with allowing new stacks:
-	for (int i = 0; i < NumSlots; i++)
-	{
-		if (Grid.IsSlotEmpty(i))
-		{
-			continue;
-		}
-		if (MoveItemsFromSlot(a_Entity, i, true))
+		if (MoveItemsFromSlot(a_Entity, i))
 		{
 			Grid.ChangeSlotCount(i, -1);
 			return true;
@@ -495,21 +480,19 @@ bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity)
 
 
 /// Moves one piece of the specified a_Entity's slot itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack.
-bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SlotNum, bool a_AllowNewStacks)
+bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SlotNum)
 {
 	cItem One(a_Entity.GetSlot(a_SlotNum).CopyOne());
 	for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
 	{
 		if (m_Contents.IsSlotEmpty(i))
 		{
-			if (a_AllowNewStacks)
+			if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum))
 			{
-				if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum))
-				{
-					// Plugin disagrees with the move
-					continue;
-				}
+				// Plugin disagrees with the move
+				continue;
 			}
+
 			m_Contents.SetSlot(i, One);
 			return true;
 		}
@@ -521,8 +504,14 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
 				continue;
 			}
 
+			auto PreviousCount = m_Contents.GetSlot(i).m_ItemCount;
 			m_Contents.ChangeSlotCount(i, 1);
-			return true;
+
+			if (PreviousCount == m_Contents.GetSlot(i).m_ItemCount + 1)
+			{
+				// Successfully added a new item. (Failure condition consistutes: stack full)
+				return true;
+			}
 		}
 	}
 	return false;
diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h
index af99c526d..16d4cb6f9 100644
--- a/src/BlockEntities/HopperEntity.h
+++ b/src/BlockEntities/HopperEntity.h
@@ -74,7 +74,7 @@ protected:
 	bool MoveItemsFromGrid(cBlockEntityWithItems & a_Entity);
 	
 	/// Moves one piece from the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack.
-	bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum, bool a_AllowNewStacks);
+	bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum);
 	
 	/// Moves items to the chest at the specified coords. Returns true if contents have changed
 	bool MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ);
-- 
cgit v1.2.3


From c10e83c02d7074cde10200842451646ecca21ca6 Mon Sep 17 00:00:00 2001
From: Tiger Wang 
Date: Mon, 11 May 2015 23:21:46 +0100
Subject: Fixed creative click-outside

* Fixes #1995
---
 src/Protocol/Protocol18x.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 1d83be8dd..17faca27e 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -51,7 +51,7 @@ Implements the 1.8.x protocol classes:
 
 
 /** The slot number that the client uses to indicate "outside the window". */
-static const Int16 SLOT_NUM_OUTSIDE = -999;
+static const Int16 SLOT_NUM_OUTSIDE = -1;
 
 
 
-- 
cgit v1.2.3


From 4b97569b3a635260cc9ce71470fc9b09cfb38167 Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Tue, 12 May 2015 09:20:54 +0200
Subject: ToLua now generates cLuaState::Push() and GetStackValue()

For classes exported through ToLua it generates the cLuaState::Push() and cLuaState::GetStackValue() functions, as well as the supporting forward declarations and typedefs.
Renamed virtual_method_hooks.lua to BindingsProcessor.lua since it no longer provides virtual method hooks and instead does additional processing when generating the bindings.
---
 src/Bindings/.gitignore               |   4 +-
 src/Bindings/AllToLua.bat             |   2 +-
 src/Bindings/AllToLua.sh              |   2 +-
 src/Bindings/AllToLua_lua.bat         |   2 +-
 src/Bindings/BindingsProcessor.lua    | 161 +++++++++++++++
 src/Bindings/CMakeLists.txt           |  13 +-
 src/Bindings/LuaState.cpp             | 377 +---------------------------------
 src/Bindings/LuaState.h               |  85 +-------
 src/Bindings/virtual_method_hooks.lua |  44 ----
 src/CMakeLists.txt                    |   2 +-
 src/CheckBasicStyle.lua               |   1 +
 11 files changed, 195 insertions(+), 498 deletions(-)
 create mode 100644 src/Bindings/BindingsProcessor.lua
 delete mode 100644 src/Bindings/virtual_method_hooks.lua

diff --git a/src/Bindings/.gitignore b/src/Bindings/.gitignore
index 0d00dd578..711ae9c3a 100644
--- a/src/Bindings/.gitignore
+++ b/src/Bindings/.gitignore
@@ -1,2 +1,4 @@
 lua51.dll
-LuaState_Call.inc
+LuaState_Declaration.inc
+LuaState_Implementation.cpp
+LuaState_Typedefs.inc
diff --git a/src/Bindings/AllToLua.bat b/src/Bindings/AllToLua.bat
index f085af9e9..44675a886 100644
--- a/src/Bindings/AllToLua.bat
+++ b/src/Bindings/AllToLua.bat
@@ -12,7 +12,7 @@
 
 :: Regenerate the files:
 echo Regenerating LUA bindings . . .
-"tolua++.exe" -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+"tolua++.exe" -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
 
 
 
diff --git a/src/Bindings/AllToLua.sh b/src/Bindings/AllToLua.sh
index 887c2490c..625ae4300 100644
--- a/src/Bindings/AllToLua.sh
+++ b/src/Bindings/AllToLua.sh
@@ -1,2 +1,2 @@
 #!/bin/bash
-/usr/bin/tolua++ -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+/usr/bin/tolua++ -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
diff --git a/src/Bindings/AllToLua_lua.bat b/src/Bindings/AllToLua_lua.bat
index 81c738f32..2d52c022d 100644
--- a/src/Bindings/AllToLua_lua.bat
+++ b/src/Bindings/AllToLua_lua.bat
@@ -13,7 +13,7 @@
 
 :: Regenerate the files:
 echo Regenerating LUA bindings . . .
-lua ..\..\lib\tolua++\src\bin\lua\_driver.lua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+lua ..\..\lib\tolua++\src\bin\lua\_driver.lua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
 
 
 
diff --git a/src/Bindings/BindingsProcessor.lua b/src/Bindings/BindingsProcessor.lua
new file mode 100644
index 000000000..f86be6c6d
--- /dev/null
+++ b/src/Bindings/BindingsProcessor.lua
@@ -0,0 +1,161 @@
+
+-- BindingsProcessor.lua
+
+-- Implements additional processing that is done while generating the Lua bindings
+
+
+
+
+
+local access = {public = 0, protected = 1, private = 2}
+
+
+
+
+
+--- Defines classes that have a custom manual Push() implementation and should not generate the automatic one
+-- Map of classname -> true
+local g_HasCustomPushImplementation =
+{
+	cEntity = true
+}
+
+
+
+
+
+function parser_hook(s)
+	local container = classContainer.curr -- get the current container
+
+	-- process access-specifying labels (public, private, etc)
+	do
+		local b, e, label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
+		if b then
+
+			-- found a label, get the new access value from the global 'access' table
+			if access[label] then
+				container.curr_member_access = access[label]
+			end -- else ?
+
+			return strsub(s, e) -- normally we would use 'e+1', but we need to preserve the [^:]
+		end
+	end
+end
+
+
+
+
+
+--- Outputs the helper files supplementing the cLuaState class
+-- Writes:
+--   LuaState_Declaration.inc
+--   LuaState_Implementation.cpp
+--   LuaState_Typedefs.inc
+local function OutputLuaStateHelpers(a_Package)
+	-- Collect all class types from ToLua:
+	local types = {}
+	for idx, item in ipairs(a_Package) do
+		local mt = getmetatable(item) or {}
+		if (mt.classtype == "class") then
+			table.insert(types, {name = item.name, lname = item.lname})
+		end
+	end
+	table.sort(types,
+		function(a_Item1, a_Item2)
+			return (a_Item1.name:lower() < a_Item2.name:lower())
+		end
+	)
+
+	-- Output the typedefs:
+	do
+		local f = assert(io.open("LuaState_Typedefs.inc", "w"))
+		f:write("\n// LuaState_Typedefs.inc\n\n// This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo.\n")
+		f:write("// Provides a forward declaration and a typedef for a pointer to each class exported to the Lua API.\n")
+		f:write("\n\n\n\n\n")
+		for _, item in ipairs(types) do
+			if not(item.name:match(".*<.*")) then  -- Skip templates altogether
+				-- Classes start with a "c", everything else is a struct:
+				if (item.name:sub(1, 1) == "c") then
+					f:write("class " .. item.name .. ";\n")
+				else
+					f:write("struct " .. item.name .. ";\n")
+				end
+			end
+		end
+		f:write("\n\n\n\n\n")
+		for _, item in ipairs(types) do
+			f:write("typedef " .. item.name .. " * Ptr" .. item.lname .. ";\n")
+		end
+		f:write("\n\n\n\n\n")
+		f:close()
+	end
+	
+	-- Output the Push() and GetStackValue() function declarations:
+	do
+		local f = assert(io.open("LuaState_Declaration.inc", "w"))
+		f:write("\n// LuaState_Declaration.inc\n\n// This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo.\n")
+		f:write("// Implements a Push() and GetStackValue() function for each class exported to the Lua API.\n")
+		f:write("// This file expects to be included form inside the cLuaState class definition\n")
+		f:write("\n\n\n\n\n")
+		for _, item in ipairs(types) do
+			f:write("void Push(" .. item.name .. " * a_Value);\n")
+		end
+		for _, item in ipairs(types) do
+			f:write("void GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal);\n")
+		end
+		f:write("\n\n\n\n\n")
+		f:close()
+	end
+
+	-- Output the Push() and GetStackValue() function implementations:
+	do
+		local f = assert(io.open("LuaState_Implementation.cpp", "w"))
+		f:write("\n// LuaState_Implementation.cpp\n\n// This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo.\n")
+		f:write("// Implements a Push() and GetStackValue() function for each class exported to the Lua API.\n")
+		f:write("// This file expects to be compiled as a separate translation unit\n")
+		f:write("\n\n\n\n\n")
+		f:write("#include \"Globals.h\"\n#include \"LuaState.h\"\n#include \"tolua++/include/tolua++.h\"\n")
+		f:write("\n\n\n\n\n")
+		for _, item in ipairs(types) do
+			if not(g_HasCustomPushImplementation[item.name]) then
+				f:write("void cLuaState::Push(" .. item.name .. " * a_Value)\n{\n\tASSERT(IsValid());\n")
+				f:write("\ttolua_pushusertype(m_LuaState, a_Value, \"" .. item.name .. "\");\n");
+				f:write("\tm_NumCurrentFunctionArgs += 1;\n")
+				f:write("}\n\n\n\n\n\n")
+			end
+		end
+		for _, item in ipairs(types) do
+			f:write("void cLuaState::GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n")
+			f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n")
+			f:write("\t	a_ReturnedVal = nullptr;\n")
+			f:write("\t	return;\n\t}\n")
+			f:write("\ttolua_Error err;\n")
+			f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"" .. item.name .. "\", false, &err))\n")
+			f:write("\t{\n")
+			f:write("\t	a_ReturnedVal = *(reinterpret_cast<" .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n")
+			f:write("\t}\n")
+			f:write("}\n\n\n\n\n\n")
+		end
+		f:close()
+	end
+end
+
+
+
+
+
+function pre_output_hook(a_Package)
+	OutputLuaStateHelpers(a_Package)
+end
+
+
+
+
+
+function post_output_hook()
+	print("Bindings have been generated.")
+end
+
+
+
+
diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt
index 366284fcb..2cc33c21f 100644
--- a/src/Bindings/CMakeLists.txt
+++ b/src/Bindings/CMakeLists.txt
@@ -11,6 +11,7 @@ SET (SRCS
 	LuaNameLookup.cpp
 	LuaServerHandle.cpp
 	LuaState.cpp
+	LuaState_Implementation.cpp
 	LuaTCPLink.cpp
 	LuaUDPEndpoint.cpp
 	LuaWindow.cpp
@@ -31,6 +32,8 @@ SET (HDRS
 	LuaNameLookup.h
 	LuaServerHandle.h
 	LuaState.h
+	LuaState_Declaration.inc
+	LuaState_Typedefs.inc
 	LuaTCPLink.h
 	LuaUDPEndpoint.h
 	LuaWindow.h
@@ -46,12 +49,15 @@ SET (HDRS
 set (BINDING_OUTPUTS
 	${CMAKE_CURRENT_SOURCE_DIR}/Bindings.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/Bindings.h
+	${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Declaration.inc
+	${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Implementation.cpp
+	${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Typedefs.inc
 )
 
 set(BINDING_DEPENDENCIES
 	tolua
-	../Bindings/virtual_method_hooks.lua
 	../Bindings/AllToLua.pkg
+	../Bindings/BindingsProcessor.lua
 	../Bindings/LuaFunctions.h
 	../Bindings/LuaWindow.h
 	../Bindings/Plugin.h
@@ -126,7 +132,7 @@ if (NOT MSVC)
 		OUTPUT ${BINDING_OUTPUTS}
 
 		# Regenerate bindings:
-		COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+		COMMAND tolua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
 		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 
 		# add any new generation dependencies here
@@ -134,8 +140,7 @@ if (NOT MSVC)
 	)
 endif ()
 
-set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE)
-set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE)
+set_source_files_properties(${BINDING_OUTPUTS} PROPERTIES GENERATED TRUE)
 
 set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error)
 
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index fb02569c9..f58047131 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -530,42 +530,6 @@ void cLuaState::Push(bool a_Value)
 
 
 
-void cLuaState::Push(cBlockEntity * a_BlockEntity)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_BlockEntity, (a_BlockEntity == nullptr) ? "cBlockEntity" : a_BlockEntity->GetClass());
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cChunkDesc * a_ChunkDesc)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cClientHandle * a_Client)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Client, "cClientHandle");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
 void cLuaState::Push(cEntity * a_Entity)
 {
 	ASSERT(IsValid());
@@ -632,42 +596,6 @@ void cLuaState::Push(cEntity * a_Entity)
 
 
 
-void cLuaState::Push(cHopperEntity * a_Hopper)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Hopper, "cHopperEntity");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cItem * a_Item)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Item, "cItem");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cItems * a_Items)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Items, "cItems");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
 void cLuaState::Push(cLuaServerHandle * a_ServerHandle)
 {
 	ASSERT(IsValid());
@@ -704,126 +632,6 @@ void cLuaState::Push(cLuaUDPEndpoint * a_UDPEndpoint)
 
 
 
-void cLuaState::Push(cMonster * a_Monster)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Monster, "cMonster");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPickup * a_Pickup)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Pickup, "cPickup");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPlayer * a_Player)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPlugin * a_Plugin)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Plugin, "cPlugin");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPluginLua * a_Plugin)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Plugin, "cPluginLua");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cProjectileEntity * a_ProjectileEntity)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cTNTEntity * a_TNTEntity)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_TNTEntity, "cTNTEntity");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWebAdmin * a_WebAdmin)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_WebAdmin, "cWebAdmin");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWindow * a_Window)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Window, "cWindow");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWorld * a_World)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_World, "cWorld");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
 void cLuaState::Push(double a_Value)
 {
 	ASSERT(IsValid());
@@ -848,42 +656,6 @@ void cLuaState::Push(int a_Value)
 
 
 
-void cLuaState::Push(TakeDamageInfo * a_TDI)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_TDI, "TakeDamageInfo");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(Vector3d * a_Vector)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Vector, "Vector3");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(Vector3i * a_Vector)
-{
-	ASSERT(IsValid());
-
-	tolua_pushusertype(m_LuaState, a_Vector, "Vector3");
-	m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
 void cLuaState::Push(void * a_Ptr)
 {
 	UNUSED(a_Ptr);
@@ -899,6 +671,10 @@ void cLuaState::Push(void * a_Ptr)
 	m_NumCurrentFunctionArgs += 1;
 }
 
+
+
+
+
 void cLuaState::Push(std::chrono::milliseconds a_Value)
 {
 	ASSERT(IsValid());
@@ -911,6 +687,7 @@ void cLuaState::Push(std::chrono::milliseconds a_Value)
 
 
 
+/*
 void cLuaState::PushUserType(void * a_Object, const char * a_Type)
 {
 	ASSERT(IsValid());
@@ -918,6 +695,7 @@ void cLuaState::PushUserType(void * a_Object, const char * a_Type)
 	tolua_pushusertype(m_LuaState, a_Object, a_Type);
 	m_NumCurrentFunctionArgs += 1;
 }
+*/
 
 
 
@@ -1031,149 +809,6 @@ void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal)
 
 
 
-void cLuaState::GetStackValue(int a_StackPos, pBlockArea & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cBlockArea", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pMapManager & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cMapManager", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pPluginManager & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cPluginManager", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pRoot & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cRoot", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pScoreboard & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cScoreboard", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cWorld", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
-
-void cLuaState::GetStackValue(int a_StackPos, pClientHandle & a_ReturnedVal)
-{
-	if (lua_isnil(m_LuaState, a_StackPos))
-	{
-		a_ReturnedVal = nullptr;
-		return;
-	}
-	tolua_Error err;
-	if (tolua_isusertype(m_LuaState, a_StackPos, "cClientHandle", false, &err))
-	{
-		a_ReturnedVal = *(reinterpret_cast(lua_touserdata(m_LuaState, a_StackPos)));
-	}
-}
-
-
-
-
 bool cLuaState::CallFunction(int a_NumResults)
 {
 	ASSERT (m_NumCurrentFunctionArgs >= 0);  // A function must be pushed to stack first
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 959a62bb8..b38401fd8 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -33,50 +33,12 @@ extern "C"
 #include "../Vector3.h"
 #include "../Defines.h"
 #include "PluginManager.h"
+#include "LuaState_Typedefs.inc"
 
-
-
-
-
-class cBlockArea;
-class cBlockEntity;
-class cBoundingBox;
-class cChunkDesc;
-class cClientHandle;
-class cCraftingGrid;
-class cCraftingRecipe;
-class cEntity;
-class cHopperEntity;
-class cItem;
-class cItems;
+// fwd:
 class cLuaServerHandle;
 class cLuaTCPLink;
 class cLuaUDPEndpoint;
-class cMapManager;
-class cMonster;
-class cPickup;
-class cPlayer;
-class cPlugin;
-class cPluginLua;
-class cProjectileEntity;
-class cRoot;
-class cScoreboard;
-class cTNTEntity;
-class cWebAdmin;
-class cWindow;
-class cWorld;
-struct HTTPRequest;
-struct HTTPTemplateRequest;
-struct TakeDamageInfo;
-
-typedef cBlockArea *     pBlockArea;
-typedef cBoundingBox *   pBoundingBox;
-typedef cMapManager *    pMapManager;
-typedef cPluginManager * pPluginManager;
-typedef cRoot *          pRoot;
-typedef cScoreboard *    pScoreboard;
-typedef cWorld *         pWorld;
-typedef cClientHandle *  pClientHandle;
 
 
 
@@ -214,35 +176,15 @@ public:
 	void Push(const Vector3i & a_Vector);
 	void Push(const Vector3i * a_Vector);
 
-	// Push a value onto the stack (keep alpha-sorted):
+	// Push a simple value onto the stack (keep alpha-sorted):
 	void Push(bool a_Value);
-	void Push(cBlockEntity * a_BlockEntity);
-	void Push(cChunkDesc * a_ChunkDesc);
-	void Push(cClientHandle * a_ClientHandle);
-	void Push(cEntity * a_Entity);
-	void Push(cHopperEntity * a_Hopper);
-	void Push(cItem * a_Item);
-	void Push(cItems * a_Items);
-	void Push(cLuaServerHandle * a_ServerHandle);
-	void Push(cLuaTCPLink * a_TCPLink);
-	void Push(cLuaUDPEndpoint * a_UDPEndpoint);
-	void Push(cMonster * a_Monster);
-	void Push(cPickup * a_Pickup);
-	void Push(cPlayer * a_Player);
-	void Push(cPlugin * a_Plugin);
-	void Push(cPluginLua * a_Plugin);
-	void Push(cProjectileEntity * a_ProjectileEntity);
-	void Push(cTNTEntity * a_TNTEntity);
-	void Push(cWebAdmin * a_WebAdmin);
-	void Push(cWindow * a_Window);
-	void Push(cWorld * a_World);
 	void Push(double a_Value);
 	void Push(int a_Value);
-	void Push(TakeDamageInfo * a_TDI);
-	void Push(Vector3d * a_Vector);
-	void Push(Vector3i * a_Vector);
 	void Push(void * a_Ptr);
 	void Push(std::chrono::milliseconds a_time);
+	void Push(cLuaServerHandle * a_ServerHandle);
+	void Push(cLuaTCPLink * a_TCPLink);
+	void Push(cLuaUDPEndpoint * a_UDPEndpoint);
 	
 	// GetStackValue() retrieves the value at a_StackPos, if it is a valid type. If not, a_Value is unchanged.
 	// Enum values are clamped to their allowed range.
@@ -252,17 +194,12 @@ public:
 	void GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result);
 	void GetStackValue(int a_StackPos, cRef & a_Ref);
 	void GetStackValue(int a_StackPos, double & a_Value);
-	void GetStackValue(int a_StackPos, float & a_ReturnedVal);
 	void GetStackValue(int a_StackPos, eWeather & a_Value);
+	void GetStackValue(int a_StackPos, float & a_ReturnedVal);
 	void GetStackValue(int a_StackPos, int & a_Value);
-	void GetStackValue(int a_StackPos, pBlockArea & a_Value);
-	void GetStackValue(int a_StackPos, pBoundingBox & a_Value);
-	void GetStackValue(int a_StackPos, pClientHandle & a_Value);
-	void GetStackValue(int a_StackPos, pMapManager & a_Value);
-	void GetStackValue(int a_StackPos, pPluginManager & a_Value);
-	void GetStackValue(int a_StackPos, pRoot & a_Value);
-	void GetStackValue(int a_StackPos, pScoreboard & a_Value);
-	void GetStackValue(int a_StackPos, pWorld & a_Value);
+
+	// Include the auto-generated Push and GetStackValue() functions:
+	#include "LuaState_Declaration.inc"
 	
 	/** Call the specified Lua function.
 	Returns true if call succeeded, false if there was an error.
@@ -441,7 +378,7 @@ protected:
 	bool PushFunction(const cTableRef & a_TableRef);
 	
 	/** Pushes a usertype of the specified class type onto the stack */
-	void PushUserType(void * a_Object, const char * a_Type);
+	// void PushUserType(void * a_Object, const char * a_Type);
 
 	/**
 	Calls the function that has been pushed onto the stack by PushFunction(),
diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua
deleted file mode 100644
index 14b0bcae5..000000000
--- a/src/Bindings/virtual_method_hooks.lua
+++ /dev/null
@@ -1,44 +0,0 @@
-
--- virtual_method_hooks.lua
-
--- Implements additional processing that is done while generating the Lua bindings
-
-
-
-
-
-local access = {public = 0, protected = 1, private = 2}
-
-
-
-
-
-function parser_hook(s)
-	local container = classContainer.curr -- get the current container
-
-	-- process access-specifying labels (public, private, etc)
-	do
-		local b, e, label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
-		if b then
-
-			-- found a label, get the new access value from the global 'access' table
-			if access[label] then
-				container.curr_member_access = access[label]
-			end -- else ?
-
-			return strsub(s, e) -- normally we would use 'e+1', but we need to preserve the [^:]
-		end
-	end
-end
-
-
-
-
-
-function post_output_hook()
-	print("Bindings have been generated.")
-end
-
-
-
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fd28f3787..2e367bcf5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -278,7 +278,7 @@ if (MSVC)
 		COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/MCServer/lua51.dll ./lua51.dll
 
 		# Regenerate bindings:
-		COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+		COMMAND tolua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
 		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
 
 		# add any new generation dependencies here
diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua
index 9ff47634d..fa20f18f7 100755
--- a/src/CheckBasicStyle.lua
+++ b/src/CheckBasicStyle.lua
@@ -43,6 +43,7 @@ local g_IgnoredFiles =
 {
 	"Bindings/Bindings.h",
 	"Bindings/Bindings.cpp",
+	"Bindings/LuaState_Implementation.cpp",
 	"LeakFinder.cpp",
 	"LeakFinder.h",
 	"MersenneTwister.h",
-- 
cgit v1.2.3


From a729cba82ebc110f4765c4fbc9c62c04153cb632 Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Tue, 12 May 2015 09:21:43 +0200
Subject: CIBuild: Added action labels

---
 CIbuild.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CIbuild.sh b/CIbuild.sh
index f5a9005da..60fed73c2 100755
--- a/CIbuild.sh
+++ b/CIbuild.sh
@@ -7,9 +7,13 @@ export MCSERVER_BUILD_ID=$TRAVIS_JOB_NUMBER
 export MCSERVER_BUILD_DATETIME=`date`
 
 cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
+
+echo "Checking basic style..."
 cd src
 lua CheckBasicStyle.lua
 cd ..
+
+echo "Building..."
 make -j 2;
 make -j 2 test ARGS="-V";
 cd MCServer/;
-- 
cgit v1.2.3


From 15771e47591379e5bc0b5feaabc013793f0ff119 Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Wed, 13 May 2015 11:30:57 +0200
Subject: Moved cWorld manual bindings out into a separate file.

---
 src/Bindings/CMakeLists.txt                 |    1 +
 src/Bindings/LuaState.cpp                   |    2 +-
 src/Bindings/ManualBindings.cpp             | 1326 +++------------------------
 src/Bindings/ManualBindings.h               |  549 ++++++++++-
 src/Bindings/ManualBindings_Network.cpp     |   22 +-
 src/Bindings/ManualBindings_RankManager.cpp |    2 +-
 src/Bindings/ManualBindings_World.cpp       |  588 ++++++++++++
 7 files changed, 1263 insertions(+), 1227 deletions(-)
 create mode 100644 src/Bindings/ManualBindings_World.cpp

diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt
index 2cc33c21f..133c2224d 100644
--- a/src/Bindings/CMakeLists.txt
+++ b/src/Bindings/CMakeLists.txt
@@ -18,6 +18,7 @@ SET (SRCS
 	ManualBindings.cpp
 	ManualBindings_Network.cpp
 	ManualBindings_RankManager.cpp
+	ManualBindings_World.cpp
 	Plugin.cpp
 	PluginLua.cpp
 	PluginManager.cpp
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index f58047131..ccf812417 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -107,7 +107,7 @@ void cLuaState::Create(void)
 void cLuaState::RegisterAPILibs(void)
 {
 	tolua_AllToLua_open(m_LuaState);
-	ManualBindings::Bind(m_LuaState);
+	cManualBindings::Bind(m_LuaState);
 	DeprecatedBindings::Bind(m_LuaState);
 	luaopen_lsqlite3(m_LuaState);
 	luaopen_lxp(m_LuaState);
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index bfe280f51..324ca9b89 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -33,7 +33,6 @@
 #include "../WorldStorage/SchematicFileSerializer.h"
 #include "../CompositeChat.h"
 #include "../StringCompression.h"
-#include "../Broadcaster.h"
 #include "../CommandOutput.h"
 
 
@@ -41,7 +40,7 @@
 
 
 // Better error reporting for Lua
-static int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
+int cManualBindings::tolua_do_error(lua_State * L, const char * a_pMsg, tolua_Error * a_pToLuaError)
 {
 	// Retrieve current function name
 	lua_Debug entry;
@@ -61,7 +60,7 @@ static int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pTo
 
 
 
-static int lua_do_error(lua_State* L, const char * a_pFormat, ...)
+int cManualBindings::lua_do_error(lua_State * L, const char * a_pFormat, ...)
 {
 	// Retrieve current function name
 	lua_Debug entry;
@@ -93,12 +92,12 @@ static int tolua_Clamp(lua_State * tolua_S)
 	int NumArgs = lua_gettop(LuaState);
 	if (NumArgs != 3)
 	{
-		return lua_do_error(LuaState, "Error in function call '#funcname#': Requires 3 arguments, got %i", NumArgs);
+		return cManualBindings::lua_do_error(LuaState, "Error in function call '#funcname#': Requires 3 arguments, got %i", NumArgs);
 	}
 
 	if (!lua_isnumber(LuaState, 1) || !lua_isnumber(LuaState, 2) || !lua_isnumber(LuaState, 3))
 	{
-		return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3");
+		return cManualBindings::lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3");
 	}
 
 	lua_Number Number = tolua_tonumber(LuaState, 1, 0);
@@ -290,12 +289,20 @@ static int tolua_StringSplitWithQuotes(lua_State * tolua_S)
 
 static int tolua_StringSplitAndTrim(lua_State * tolua_S)
 {
-	cLuaState LuaState(tolua_S);
-	std::string str   = (std::string)tolua_tocppstring(LuaState, 1, 0);
-	std::string delim = (std::string)tolua_tocppstring(LuaState, 2, 0);
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamString(1, 2) ||
+		!L.CheckParamEnd(3)
+	)
+	{
+		return 0;
+	}
 
-	AStringVector Split = StringSplitAndTrim(str, delim);
-	LuaState.Push(Split);
+	// Process:
+	AString str, delim;
+	L.GetStackValues(1, str, delim);
+	L.Push(StringSplitAndTrim(str, delim));
 	return 1;
 }
 
@@ -454,7 +461,7 @@ static int tolua_Base64Decode(lua_State * tolua_S)
 
 
 
-cPluginLua * GetLuaPlugin(lua_State * L)
+cPluginLua * cManualBindings::GetLuaPlugin(lua_State * L)
 {
 	// Get the plugin identification out of LuaState:
 	lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
@@ -503,910 +510,23 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S)
 static int tolua_cFile_ReadWholeFile(lua_State * tolua_S)
 {
 	// Check params:
-	cLuaState LuaState(tolua_S);
-	if (
-		!LuaState.CheckParamUserTable(1, "cFile") ||
-		!LuaState.CheckParamString   (2) ||
-		!LuaState.CheckParamEnd      (3)
-	)
-	{
-		return 0;
-	}
-	
-	// Get params:
-	AString FileName;
-	LuaState.GetStackValues(2, FileName);
-
-	// Execute and push result:
-	LuaState.Push(cFile::ReadWholeFile(FileName));
-	return 1;
-}
-
-
-
-
-
-/** Binds the DoWith(ItemName) functions of regular classes. */
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*DoWithFn)(const AString &, cItemCallback &)
->
-static int tolua_DoWith(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamString(2) ||
-		!L.CheckParamFunction(3)
-	)
-	{
-		return 0;
-	}
-
-	// Get parameters:
-	Ty1 * Self;
-	AString ItemName;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, ItemName, FnRef);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-	if (ItemName.empty() || (ItemName[0] == 0))
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool ret = false;
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
-			return ret;
-		}
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-	} Callback(L, FnRef);
-
-	// Call the DoWith function:
-	bool res = (Self->*DoWithFn)(ItemName, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-/** Template for static functions DoWith(ItemName), on a type that has a static ::Get() function. */
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*DoWithFn)(const AString &, cItemCallback &)
->
-static int tolua_StaticDoWith(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamString(2) ||
-		!L.CheckParamFunction(3)
-	)
-	{
-		return 0;
-	}
-
-	// Get parameters:
-	AString ItemName;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(2, ItemName, FnRef);
-	if (ItemName.empty() || (ItemName[0] == 0))
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool ret = false;
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
-			return ret;
-		}
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-	} Callback(L, FnRef);
-
-	// Call the DoWith function:
-	bool res = (Ty1::Get()->*DoWithFn)(ItemName, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*DoWithFn)(UInt32, cItemCallback &)
->
-static int tolua_DoWithID(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamNumber(2) ||
-		!L.CheckParamFunction(3)
-	)
-	{
-		return 0;
-	}
-
-	// Get parameters:
-	Ty1 * Self = nullptr;
-	int ItemID;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, ItemID, FnRef);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool ret = false;
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
-			return ret;
-		}
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-	} Callback(L, FnRef);
-
-	// Call the DoWith function:
-	bool res = (Self->*DoWithFn)(ItemID, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*DoWithFn)(int, int, int, cItemCallback &)
->
-static int tolua_DoWithXYZ(lua_State* tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamNumber(2, 5) ||
-		!L.CheckParamFunction(6)
-	)
-	{
-		return 0;
-	}
-
-	// Get parameters:
-	Ty1 * Self = nullptr;
-	int BlockX, BlockY, BlockZ;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ, FnRef);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #5");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool ret = false;
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
-			return ret;
-		}
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-	} Callback(L, FnRef);
-
-	// Call the DoWith function:
-	bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*ForEachFn)(int, int, cItemCallback &)
->
-static int tolua_ForEachInChunk(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamNumber(2, 4) ||
-		!L.CheckParamFunction(5)
-	)
-	{
-		return 0;
-	}
-
-	// Get parameters:
-	Ty1 * Self = nullptr;
-	int ChunkX, ChunkZ;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, ChunkX, ChunkZ, FnRef);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #4");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool ret = false;
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
-			return ret;
-		}
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-	} Callback(L, FnRef);
-
-	// Call the DoWith function:
-	bool res = (Self->*ForEachFn)(ChunkX, ChunkZ, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*ForEachFn)(const cBoundingBox &, cItemCallback &)
->
-static int tolua_ForEachInBox(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamUserType(2, "cBoundingBox") ||
-		!L.CheckParamFunction(3) ||
-		!L.CheckParamEnd(4)
-	)
-	{
-		return 0;
-	}
-
-	// Get the params:
-	Ty1 * Self = nullptr;
-	cBoundingBox * Box = nullptr;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, Box, FnRef);
-	if ((Self == nullptr) || (Box == nullptr))
-	{
-		LOGWARNING("Invalid world (%p) or boundingbox (%p)", Self, Box);
-		L.LogStackTrace();
-		return 0;
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
-	}
-
-	// Callback wrapper for the Lua function:
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) :
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FuncRef)
-		{
-		}
-
-	private:
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-
-		// cItemCallback overrides:
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool res = false;
-			if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res))
-			{
-				LOGWARNING("Failed to call Lua callback");
-				m_LuaState.LogStackTrace();
-				return true;  // Abort enumeration
-			}
-
-			return res;
-		}
-	} Callback(L, FnRef);
-
-	bool res = (Self->*ForEachFn)(*Box, Callback);
-
-	// Push the result as the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*ForEachFn)(cItemCallback &)
->
-static int tolua_ForEach(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamFunction(2) ||
-		!L.CheckParamEnd(3)
-	)
-	{
-		return 0;
-	}
-
-	// Get the params:
-	Ty1 * Self = nullptr;
-	cLuaState::cRef FnRef;
-	L.GetStackValues(1, Self, FnRef);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'.");
-	}
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool res = false;  // By default continue the enumeration
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
-			return res;
-		}
-	} Callback(L, FnRef);
-
-	// Call the enumeration:
-	bool res = (Self->*ForEachFn)(Callback);
-
-	// Push the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-/** Implements bindings for ForEach() functions in a class that is static (has a ::Get() static function). */
-template <
-	class Ty1,
-	class Ty2,
-	bool (Ty1::*ForEachFn)(cItemCallback &)
->
-static int tolua_StaticForEach(lua_State * tolua_S)
-{
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamFunction(2) ||
-		!L.CheckParamEnd(3)
-	)
-	{
-		return 0;
-	}
-
-	// Get the params:
-	cLuaState::cRef FnRef(L, 2);
-	if (!FnRef.IsValid())
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
-	}
-
-	class cLuaCallback : public cItemCallback
-	{
-	public:
-		cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
-			m_LuaState(a_LuaState),
-			m_FnRef(a_FnRef)
-		{
-		}
-
-	private:
-		cLuaState & m_LuaState;
-		cLuaState::cRef & m_FnRef;
-
-		virtual bool Item(Ty2 * a_Item) override
-		{
-			bool res = false;  // By default continue the enumeration
-			m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
-			return res;
-		}
-	} Callback(L, FnRef);
-
-	// Call the enumeration:
-	bool res = (Ty1::Get()->*ForEachFn)(Callback);
-
-	// Push the return value:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-
-static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S)
-{
-	// Exported manually, because tolua would generate useless additional parameters (a_BlockType .. a_BlockSkyLight)
-	// Function signature: GetBlockInfo(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta, BlockSkyLight, BlockBlockLight]
-
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamNumber(2, 4) ||
-		!L.CheckParamEnd(5)
-	)
-	{
-		return 0;
-	}
-
-	// Get params:
-	cWorld * Self = nullptr;
-	int BlockX, BlockY, BlockZ;
-	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-
-	// Call the function:
-	BLOCKTYPE BlockType;
-	NIBBLETYPE BlockMeta, BlockSkyLight, BlockBlockLight;
-	bool res = Self->GetBlockInfo(BlockX, BlockY, BlockZ, BlockType, BlockMeta, BlockSkyLight, BlockBlockLight);
-
-	// Push the returned values:
-	L.Push(res);
-	if (res)
-	{
-		L.Push(BlockType);
-		L.Push(BlockMeta);
-		L.Push(BlockSkyLight);
-		L.Push(BlockBlockLight);
-		return 5;
-	}
-	return 1;
-}
-
-
-
-
-
-static int tolua_cWorld_GetBlockTypeMeta(lua_State * tolua_S)
-{
-	// Exported manually, because tolua would generate useless additional parameters (a_BlockType, a_BlockMeta)
-	// Function signature: GetBlockTypeMeta(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta]
-
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamNumber(2, 4) ||
-		!L.CheckParamEnd(5)
-	)
-	{
-		return 0;
-	}
-
-	// Get params:
-	cWorld * Self = nullptr;
-	int BlockX, BlockY, BlockZ;
-	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-
-	// Call the function:
-	BLOCKTYPE BlockType;
-	NIBBLETYPE BlockMeta;
-	bool res = Self->GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockType, BlockMeta);
-
-	// Push the returned values:
-	L.Push(res);
-	if (res)
-	{
-		L.Push(BlockType);
-		L.Push(BlockMeta);
-		return 3;
-	}
-	return 1;
-}
-
-
-
-
-
-static int tolua_cWorld_GetSignLines(lua_State * tolua_S)
-{
-	// Exported manually, because tolua would generate useless additional parameters (a_Line1 .. a_Line4)
-
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamNumber(2, 4) ||
-		!L.CheckParamEnd(5)
-	)
-	{
-		return 0;
-	}
-
-	// Get params:
-	cWorld * Self = nullptr;
-	int BlockX, BlockY, BlockZ;
-	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-
-	// Call the function:
-	AString Line1, Line2, Line3, Line4;
-	bool res = Self->GetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
-
-	// Push the returned values:
-	L.Push(res);
-	if (res)
-	{
-		L.Push(Line1);
-		L.Push(Line2);
-		L.Push(Line3);
-		L.Push(Line4);
-		return 5;
-	}
-	return 1;
-}
-
-
-
-
-
-static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
-{
-	// Exported manually, because tolua would generate useless additional return values (a_Line1 .. a_Line4)
-
-	// Check params:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamNumber(2, 4) ||
-		!L.CheckParamString(5, 8) ||
-		!L.CheckParamEnd(9)
-	)
-	{
-		return 0;
-	}
-
-	// Get params:
-	cWorld * Self = nullptr;
-	int BlockX, BlockY, BlockZ;
-	AString Line1, Line2, Line3, Line4;
-	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
-	if (Self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
-	}
-
-	// Call the function:
-	bool res = Self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
-
-	// Push the returned values:
-	L.Push(res);
-	return 1;
-}
-
-
-
-
-static int tolua_cWorld_TryGetHeight(lua_State * tolua_S)
-{
-	// Exported manually, because tolua would require the out-only param a_Height to be used when calling
-	// Takes a_World, a_BlockX, a_BlockZ
-	// Returns Height, IsValid
-	#ifndef TOLUA_RELEASE
-	tolua_Error tolua_err;
-	if (
-		!tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) ||
-		!tolua_isnumber   (tolua_S, 2, 0, &tolua_err) ||
-		!tolua_isnumber   (tolua_S, 3, 0, &tolua_err) ||
-		!tolua_isnoobj    (tolua_S, 4, &tolua_err)
-		)
-		goto tolua_lerror;
-	else
-	#endif
-	{
-		cWorld * self       = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr);
-		int BlockX          = (int)      tolua_tonumber   (tolua_S, 2, 0);
-		int BlockZ          = (int)      tolua_tonumber   (tolua_S, 3, 0);
-		#ifndef TOLUA_RELEASE
-		if (self == nullptr)
-		{
-			tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", nullptr);
-		}
-		#endif
-		{
-			int Height = 0;
-			bool res = self->TryGetHeight(BlockX, BlockZ, Height);
-			tolua_pushboolean(tolua_S, res ? 1 : 0);
-			if (res)
-			{
-				tolua_pushnumber(tolua_S, Height);
-				return 2;
-			}
-		}
-	}
-	return 1;
-	
-	#ifndef TOLUA_RELEASE
-tolua_lerror:
-	tolua_error(tolua_S, "#ferror in function 'TryGetHeight'.", &tolua_err);
-	return 0;
-	#endif
-}
-
-
-
-
-
-class cLuaWorldTask :
-	public cWorld::cTask,
-	public cPluginLua::cResettable
-{
-public:
-	cLuaWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
-		cPluginLua::cResettable(a_Plugin),
-		m_FnRef(a_FnRef)
-	{
-	}
-
-protected:
-	int m_FnRef;
-	
-	// cWorld::cTask overrides:
-	virtual void Run(cWorld & a_World) override
-	{
-		cCSLock Lock(m_CSPlugin);
-		if (m_Plugin != nullptr)
-		{
-			m_Plugin->Call(m_FnRef, &a_World);
-		}
-	}
-} ;
-
-
-
-
-
-static int tolua_cWorld_QueueTask(lua_State * tolua_S)
-{
-	// Binding for cWorld::QueueTask
-	// Params: function
-	
-	// Retrieve the cPlugin from the LuaState:
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
-	if (Plugin == nullptr)
-	{
-		// An error message has been already printed in GetLuaPlugin()
-		return 0;
-	}
-
-	// Retrieve the args:
-	cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
-	if (self == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
-	}
-	if (!lua_isfunction(tolua_S, 2))
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #1");
-	}
-
-	// Create a reference to the function:
-	int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
-	if (FnRef == LUA_REFNIL)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
-	}
-
-	auto task = std::make_shared(*Plugin, FnRef);
-	Plugin->AddResettable(task);
-	self->QueueTask(task);
-	return 0;
-}
-
-
-
-
-
-class cLuaScheduledWorldTask :
-	public cWorld::cTask,
-	public cPluginLua::cResettable
-{
-public:
-	cLuaScheduledWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
-		cPluginLua::cResettable(a_Plugin),
-		m_FnRef(a_FnRef)
-	{
-	}
-
-protected:
-	int m_FnRef;
-	
-	// cWorld::cTask overrides:
-	virtual void Run(cWorld & a_World) override
-	{
-		cCSLock Lock(m_CSPlugin);
-		if (m_Plugin != nullptr)
-		{
-			m_Plugin->Call(m_FnRef, &a_World);
-		}
-	}
-};
-
-
-
-
-
-static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
-{
-	// Binding for cWorld::ScheduleTask
-	// Params: function, Ticks
-	
-	// Retrieve the cPlugin from the LuaState:
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
-	if (Plugin == nullptr)
-	{
-		// An error message has been already printed in GetLuaPlugin()
-		return 0;
-	}
-
-	// Retrieve the args:
-	cLuaState L(tolua_S);
+	cLuaState LuaState(tolua_S);
 	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamNumber  (2) ||
-		!L.CheckParamFunction(3)
+		!LuaState.CheckParamUserTable(1, "cFile") ||
+		!LuaState.CheckParamString   (2) ||
+		!LuaState.CheckParamEnd      (3)
 	)
 	{
 		return 0;
 	}
-	cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
-	if (World == nullptr)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
-	}
-
-	// Create a reference to the function:
-	int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
-	if (FnRef == LUA_REFNIL)
-	{
-		return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
-	}
 	
-	int DelayTicks = (int)tolua_tonumber(tolua_S, 2, 0);
+	// Get params:
+	AString FileName;
+	LuaState.GetStackValues(2, FileName);
 
-	auto task = std::make_shared(*Plugin, FnRef);
-	Plugin->AddResettable(task);
-	World->ScheduleTask(DelayTicks, task);
-	return 0;
+	// Execute and push result:
+	LuaState.Push(cFile::ReadWholeFile(FileName));
+	return 1;
 }
 
 
@@ -1430,7 +550,7 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S)
 
 static int tolua_cPluginManager_GetCurrentPlugin(lua_State * S)
 {
-	cPluginLua * Plugin = GetLuaPlugin(S);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(S);
 	if (Plugin == nullptr)
 	{
 		// An error message has already been printed in GetLuaPlugin()
@@ -1473,7 +593,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager,
 	// The arg types have already been checked
 	
 	// Retrieve the cPlugin from the LuaState:
-	cPluginLua * Plugin = GetLuaPlugin(S);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(S);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -1520,7 +640,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager,
 		S.LogStackTrace();
 		return 0;
 	}
-	if (Plugin != GetLuaPlugin(S))
+	if (Plugin != cManualBindings::GetLuaPlugin(S))
 	{
 		// The plugin parameter passed to us is not our stored plugin. Disallow this!
 		LOGWARNING("cPluginManager.AddHook(): Invalid Plugin parameter, cannot add hook to foreign plugins. Hook not added.");
@@ -1787,7 +907,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L)
 		cPluginManager:BindCommand(Command, Permission, Function, HelpString)
 		cPluginManager.BindCommand(Command, Permission, Function, HelpString)  -- without the "self" param
 	*/
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		return 0;
@@ -1857,7 +977,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L)
 	*/
 	
 	// Get the plugin identification out of LuaState:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		return 0;
@@ -1945,7 +1065,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S)
 	}
 	
 	// If requesting calling the current plugin, refuse:
-	cPluginLua * ThisPlugin = GetLuaPlugin(L);
+	cPluginLua * ThisPlugin = cManualBindings::GetLuaPlugin(L);
 	if (ThisPlugin == nullptr)
 	{
 		return 0;
@@ -2051,175 +1171,6 @@ static int tolua_cPluginManager_FindPlugins(lua_State * tolua_S)
 
 
 
-static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S)
-{
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType(1, "cWorld") ||
-		!L.CheckParamString  (2) ||
-		!L.CheckParamNumber  (3, 10)
-	)
-	{
-		return 0;
-	}
-	
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
-	if (Plugin == nullptr)
-	{
-		return 0;
-	}
-	
-	// Read the params:
-	cWorld * World = nullptr;
-	AString Name;
-	float PosX, PosY, PosZ, OffX, OffY, OffZ;
-	float ParticleData;
-	int ParticleAmmount;
-	L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmmount);
-	if (World == nullptr)
-	{
-		LOGWARNING("World:BroadcastParticleEffect(): invalid world parameter");
-		L.LogStackTrace();
-		return 0;
-	}
-
-	std::array data;
-
-	for (int i = 0; (i < 2) && L.IsParamNumber(11 + i); i++)
-	{
-		L.GetStackValue(11 + i, data[i]);
-	}
-
-	cClientHandle * Exclude = nullptr;
-
-	if (L.IsParamUserType(11, "cClientHandle"))
-	{
-		L.GetStackValue(11, Exclude);
-	}
-	World->GetBroadcaster().BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmmount, Exclude);
-
-	return 0;
-}
-
-
-
-
-
-static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
-{
-	/* Function signature:
-	World:ChunkStay(ChunkCoordTable, OnChunkAvailable, OnAllChunksAvailable)
-	ChunkCoordTable == { {Chunk1x, Chunk1z}, {Chunk2x, Chunk2z}, ... }
-	*/
-	
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType     (1, "cWorld") ||
-		!L.CheckParamTable        (2) ||
-		!L.CheckParamFunctionOrNil(3, 4)
-	)
-	{
-		return 0;
-	}
-	
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
-	if (Plugin == nullptr)
-	{
-		return 0;
-	}
-	
-	// Read the params:
-	cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
-	if (World == nullptr)
-	{
-		LOGWARNING("World:ChunkStay(): invalid world parameter");
-		L.LogStackTrace();
-		return 0;
-	}
-
-	cLuaChunkStay * ChunkStay = new cLuaChunkStay(*Plugin);
-
-	if (!ChunkStay->AddChunks(2))
-	{
-		delete ChunkStay;
-		ChunkStay = nullptr;
-		return 0;
-	}
-
-	ChunkStay->Enable(*World->GetChunkMap(), 3, 4);
-	return 0;
-}
-
-
-
-
-
-static int tolua_cWorld_PrepareChunk(lua_State * tolua_S)
-{
-	/* Function signature:
-	World:PrepareChunk(ChunkX, ChunkZ, Callback)
-	*/
-	
-	// Check the param types:
-	cLuaState L(tolua_S);
-	if (
-		!L.CheckParamUserType     (1, "cWorld") ||
-		!L.CheckParamNumber       (2, 3) ||
-		!L.CheckParamFunctionOrNil(4)
-	)
-	{
-		return 0;
-	}
-	
-	// Read the params:
-	cWorld * world = nullptr;
-	int chunkX = 0, chunkZ = 0;
-	L.GetStackValues(1, world, chunkX, chunkZ);
-	if (world == nullptr)
-	{
-		LOGWARNING("World:PrepareChunk(): invalid world parameter");
-		L.LogStackTrace();
-		return 0;
-	}
-
-	// Wrap the Lua callback inside a C++ callback class:
-	class cCallback:
-		public cChunkCoordCallback
-	{
-	public:
-		cCallback(lua_State * a_LuaState):
-			m_LuaState(a_LuaState),
-			m_Callback(m_LuaState, 4)
-		{
-		}
-
-		// cChunkCoordCallback override:
-		virtual void Call(int a_CBChunkX, int a_CBChunkZ) override
-		{
-			if (m_Callback.IsValid())
-			{
-				m_LuaState.Call(m_Callback, a_CBChunkX, a_CBChunkZ);
-			}
-
-			// This is the last reference of this object, we must delete it so that it doesn't leak:
-			delete this;
-		}
-
-	protected:
-		cLuaState m_LuaState;
-		cLuaState::cRef m_Callback;
-	};
-	cCallback * callback = new cCallback(tolua_S);
-
-	// Call the chunk preparation:
-	world->PrepareChunk(chunkX, chunkZ, callback);
-	return 0;
-}
-
-
-
-
-
 static int tolua_cPlayer_GetPermissions(lua_State * tolua_S)
 {
 	// Function signature: cPlayer:GetPermissions() -> {permissions-array}
@@ -2287,7 +1238,7 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S)
 	// Function signature: cPlayer:OpenWindow(Window)
 
 	// Retrieve the plugin instance from the Lua state
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
 	if (Plugin == nullptr)
 	{
 		return 0;
@@ -2368,7 +1319,7 @@ static int tolua_SetObjectCallback(lua_State * tolua_S)
 	// Function signature: OBJTYPE:SetWhateverCallback(CallbackFunction)
 
 	// Retrieve the plugin instance from the Lua state
-	cPluginLua * Plugin = GetLuaPlugin(tolua_S);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
 	if (Plugin == nullptr)
 	{
 		// Warning message has already been printed by GetLuaPlugin(), bail out silently
@@ -2420,7 +1371,7 @@ static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S)
 	}
 	else
 	{
-		return tolua_do_error(tolua_S, "#ferror calling function '#funcname#'", &tolua_err);
+		return cManualBindings::tolua_do_error(tolua_S, "#ferror calling function '#funcname#'", &tolua_err);
 	}
 
 	if (Reference != LUA_REFNIL)
@@ -3817,17 +2768,17 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S)
 
 
 
-void ManualBindings::Bind(lua_State * tolua_S)
+void cManualBindings::Bind(lua_State * tolua_S)
 {
 	tolua_beginmodule(tolua_S, nullptr);
 
 		// Create the new classes:
 		tolua_usertype(tolua_S, "cCryptoHash");
-		tolua_cclass(tolua_S, "cCryptoHash", "cCryptoHash", "", nullptr);
+		tolua_usertype(tolua_S, "cLineBlockTracer");
 		tolua_usertype(tolua_S, "cStringCompression");
+		tolua_cclass(tolua_S, "cCryptoHash",        "cCryptoHash",        "", nullptr);
+		tolua_cclass(tolua_S, "cLineBlockTracer",   "cLineBlockTracer",   "", nullptr);
 		tolua_cclass(tolua_S, "cStringCompression", "cStringCompression", "", nullptr);
-		tolua_usertype(tolua_S, "cLineBlockTracer");
-		tolua_cclass(tolua_S, "cLineBlockTracer", "cLineBlockTracer", "", nullptr);
 
 		// Globals:
 		tolua_function(tolua_S, "Clamp",                 tolua_Clamp);
@@ -3842,12 +2793,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
 		tolua_function(tolua_S, "Base64Encode",          tolua_Base64Encode);
 		tolua_function(tolua_S, "Base64Decode",          tolua_Base64Decode);
 		tolua_function(tolua_S, "md5",                   tolua_md5_obsolete);  // OBSOLETE, use cCryptoHash.md5() instead
-		
-		tolua_beginmodule(tolua_S, "cFile");
-			tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents);
-			tolua_function(tolua_S, "ReadWholeFile",     tolua_cFile_ReadWholeFile);
-		tolua_endmodule(tolua_S);
-		
+
 		tolua_beginmodule(tolua_S, "cBlockArea");
 			tolua_function(tolua_S, "GetBlockTypeMeta",        tolua_cBlockArea_GetBlockTypeMeta);
 			tolua_function(tolua_S, "GetCoordRange",           tolua_cBlockArea_GetCoordRange);
@@ -3860,7 +2806,13 @@ void ManualBindings::Bind(lua_State * tolua_S)
 			tolua_function(tolua_S, "SaveToSchematicFile",     tolua_cBlockArea_SaveToSchematicFile);
 			tolua_function(tolua_S, "SaveToSchematicString",   tolua_cBlockArea_SaveToSchematicString);
 		tolua_endmodule(tolua_S);
-		
+
+		tolua_beginmodule(tolua_S, "cClientHandle");
+			tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE);
+			tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE);
+			tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage);
+		tolua_endmodule(tolua_S);
+
 		tolua_beginmodule(tolua_S, "cCompositeChat");
 			tolua_function(tolua_S, "AddRunCommandPart",     tolua_cCompositeChat_AddRunCommandPart);
 			tolua_function(tolua_S, "AddSuggestCommandPart", tolua_cCompositeChat_AddSuggestCommandPart);
@@ -3870,112 +2822,105 @@ void ManualBindings::Bind(lua_State * tolua_S)
 			tolua_function(tolua_S, "SetMessageType",        tolua_cCompositeChat_SetMessageType);
 			tolua_function(tolua_S, "UnderlineUrls",         tolua_cCompositeChat_UnderlineUrls);
 		tolua_endmodule(tolua_S);
-		
+
+		tolua_beginmodule(tolua_S, "cCryptoHash");
+			tolua_function(tolua_S, "md5", tolua_md5);
+			tolua_function(tolua_S, "md5HexString", tolua_md5HexString);
+			tolua_function(tolua_S, "sha1", tolua_sha1);
+			tolua_function(tolua_S, "sha1HexString", tolua_sha1HexString);
+		tolua_endmodule(tolua_S);
+
+		tolua_beginmodule(tolua_S, "cEntity");
+			tolua_constant(tolua_S, "INVALID_ID", cEntity::INVALID_ID);
+		tolua_endmodule(tolua_S);
+
+		tolua_beginmodule(tolua_S, "cFile");
+			tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents);
+			tolua_function(tolua_S, "ReadWholeFile",     tolua_cFile_ReadWholeFile);
+		tolua_endmodule(tolua_S);
+
 		tolua_beginmodule(tolua_S, "cHopperEntity");
 			tolua_function(tolua_S, "GetOutputBlockPos", tolua_cHopperEntity_GetOutputBlockPos);
 		tolua_endmodule(tolua_S);
-		
+
+		tolua_beginmodule(tolua_S, "cItemGrid");
+			tolua_function(tolua_S, "GetSlotCoords", Lua_ItemGrid_GetSlotCoords);
+		tolua_endmodule(tolua_S);
+
 		tolua_beginmodule(tolua_S, "cLineBlockTracer");
 			tolua_function(tolua_S, "Trace", tolua_cLineBlockTracer_Trace);
 		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cRoot");
-			tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith );
-			tolua_function(tolua_S, "DoWithPlayerByUUID",  tolua_DoWith );
-			tolua_function(tolua_S, "ForEachPlayer",       tolua_ForEach);
-			tolua_function(tolua_S, "ForEachWorld",        tolua_ForEach);
-			tolua_function(tolua_S, "GetFurnaceRecipe",    tolua_cRoot_GetFurnaceRecipe);
-		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cWorld");
-			tolua_function(tolua_S, "BroadcastParticleEffect",   tolua_cWorld_BroadcastParticleEffect);
-			tolua_function(tolua_S, "ChunkStay",                 tolua_cWorld_ChunkStay);
-			tolua_function(tolua_S, "DoWithBlockEntityAt",       tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithBeaconAt",            tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithChestAt",             tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithDispenserAt",         tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithDropSpenserAt",       tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithDropperAt",           tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithEntityByID",          tolua_DoWithID< cWorld, cEntity,             &cWorld::DoWithEntityByID>);
-			tolua_function(tolua_S, "DoWithFurnaceAt",           tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithNoteBlockAt",         tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithCommandBlockAt",      tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithMobHeadAt",           tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithFlowerPotAt",         tolua_DoWithXYZ);
-			tolua_function(tolua_S, "DoWithPlayer",              tolua_DoWith<   cWorld, cPlayer,             &cWorld::DoWithPlayer>);
-			tolua_function(tolua_S, "FindAndDoWithPlayer",       tolua_DoWith<   cWorld, cPlayer,             &cWorld::FindAndDoWithPlayer>);
-			tolua_function(tolua_S, "DoWithPlayerByUUID",        tolua_DoWith<   cWorld, cPlayer,             &cWorld::DoWithPlayerByUUID>);
-			tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk);
-			tolua_function(tolua_S, "ForEachChestInChunk",       tolua_ForEachInChunk);
-			tolua_function(tolua_S, "ForEachEntity",             tolua_ForEach<       cWorld, cEntity,        &cWorld::ForEachEntity>);
-			tolua_function(tolua_S, "ForEachEntityInBox",        tolua_ForEachInBox<  cWorld, cEntity,        &cWorld::ForEachEntityInBox>);
-			tolua_function(tolua_S, "ForEachEntityInChunk",      tolua_ForEachInChunk);
-			tolua_function(tolua_S, "ForEachFurnaceInChunk",     tolua_ForEachInChunk);
-			tolua_function(tolua_S, "ForEachPlayer",             tolua_ForEach<       cWorld, cPlayer,        &cWorld::ForEachPlayer>);
-			tolua_function(tolua_S, "GetBlockInfo",              tolua_cWorld_GetBlockInfo);
-			tolua_function(tolua_S, "GetBlockTypeMeta",          tolua_cWorld_GetBlockTypeMeta);
-			tolua_function(tolua_S, "GetSignLines",              tolua_cWorld_GetSignLines);
-			tolua_function(tolua_S, "PrepareChunk",              tolua_cWorld_PrepareChunk);
-			tolua_function(tolua_S, "QueueTask",                 tolua_cWorld_QueueTask);
-			tolua_function(tolua_S, "ScheduleTask",              tolua_cWorld_ScheduleTask);
-			tolua_function(tolua_S, "SetSignLines",              tolua_cWorld_SetSignLines);
-			tolua_function(tolua_S, "TryGetHeight",              tolua_cWorld_TryGetHeight);
+
+		tolua_beginmodule(tolua_S, "cLuaWindow");
+			tolua_function(tolua_S, "SetOnClosing",     tolua_SetObjectCallback);
+			tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback);
 		tolua_endmodule(tolua_S);
-		
+
 		tolua_beginmodule(tolua_S, "cMapManager");
-			tolua_function(tolua_S, "DoWithMap", tolua_DoWithID);
+			tolua_function(tolua_S, "DoWithMap", DoWithID);
 		tolua_endmodule(tolua_S);
 
-		tolua_beginmodule(tolua_S, "cScoreboard");
-			tolua_function(tolua_S, "ForEachObjective", tolua_ForEach);
-			tolua_function(tolua_S, "ForEachTeam",      tolua_ForEach);
+		tolua_beginmodule(tolua_S, "cMojangAPI");
+			tolua_function(tolua_S, "AddPlayerNameToUUIDMapping", tolua_cMojangAPI_AddPlayerNameToUUIDMapping);
+			tolua_function(tolua_S, "GetPlayerNameFromUUID",      tolua_cMojangAPI_GetPlayerNameFromUUID);
+			tolua_function(tolua_S, "GetUUIDFromPlayerName",      tolua_cMojangAPI_GetUUIDFromPlayerName);
+			tolua_function(tolua_S, "GetUUIDsFromPlayerNames",    tolua_cMojangAPI_GetUUIDsFromPlayerNames);
+			tolua_function(tolua_S, "MakeUUIDDashed",             tolua_cMojangAPI_MakeUUIDDashed);
+			tolua_function(tolua_S, "MakeUUIDShort",              tolua_cMojangAPI_MakeUUIDShort);
 		tolua_endmodule(tolua_S);
-		
+
+		tolua_beginmodule(tolua_S, "cPlayer");
+			tolua_function(tolua_S, "GetPermissions",    tolua_cPlayer_GetPermissions);
+			tolua_function(tolua_S, "GetRestrictions",   tolua_cPlayer_GetRestrictions);
+			tolua_function(tolua_S, "OpenWindow",        tolua_cPlayer_OpenWindow);
+			tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
+		tolua_endmodule(tolua_S);
+
 		tolua_beginmodule(tolua_S, "cPlugin");
 			tolua_function(tolua_S, "GetDirectory",      tolua_cPlugin_GetDirectory);
 			tolua_function(tolua_S, "GetLocalDirectory", tolua_cPlugin_GetLocalDirectory);
 		tolua_endmodule(tolua_S);
 		
+		tolua_beginmodule(tolua_S, "cPluginLua");
+			tolua_function(tolua_S, "AddWebTab", tolua_cPluginLua_AddWebTab);
+		tolua_endmodule(tolua_S);
+
 		tolua_beginmodule(tolua_S, "cPluginManager");
 			tolua_function(tolua_S, "AddHook",               tolua_cPluginManager_AddHook);
 			tolua_function(tolua_S, "BindCommand",           tolua_cPluginManager_BindCommand);
 			tolua_function(tolua_S, "BindConsoleCommand",    tolua_cPluginManager_BindConsoleCommand);
 			tolua_function(tolua_S, "CallPlugin",            tolua_cPluginManager_CallPlugin);
-			tolua_function(tolua_S, "DoWithPlugin",          tolua_StaticDoWith);
+			tolua_function(tolua_S, "DoWithPlugin",          StaticDoWith);
 			tolua_function(tolua_S, "ExecuteConsoleCommand", tolua_cPluginManager_ExecuteConsoleCommand);
 			tolua_function(tolua_S, "FindPlugins",           tolua_cPluginManager_FindPlugins);
 			tolua_function(tolua_S, "ForEachCommand",        tolua_cPluginManager_ForEachCommand);
 			tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand);
-			tolua_function(tolua_S, "ForEachPlugin",         tolua_StaticForEach);
+			tolua_function(tolua_S, "ForEachPlugin",         StaticForEach);
 			tolua_function(tolua_S, "GetAllPlugins",         tolua_cPluginManager_GetAllPlugins);
 			tolua_function(tolua_S, "GetCurrentPlugin",      tolua_cPluginManager_GetCurrentPlugin);
 			tolua_function(tolua_S, "GetPlugin",             tolua_cPluginManager_GetPlugin);
 			tolua_function(tolua_S, "LogStackTrace",         tolua_cPluginManager_LogStackTrace);
 		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cPlayer");
-			tolua_function(tolua_S, "GetPermissions",    tolua_cPlayer_GetPermissions);
-			tolua_function(tolua_S, "GetRestrictions",   tolua_cPlayer_GetRestrictions);
-			tolua_function(tolua_S, "OpenWindow",        tolua_cPlayer_OpenWindow);
-			tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
-		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cLuaWindow");
-			tolua_function(tolua_S, "SetOnClosing",     tolua_SetObjectCallback);
-			tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback);
+
+		tolua_beginmodule(tolua_S, "cRoot");
+			tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith );
+			tolua_function(tolua_S, "DoWithPlayerByUUID",  DoWith );
+			tolua_function(tolua_S, "ForEachPlayer",       ForEach);
+			tolua_function(tolua_S, "ForEachWorld",        ForEach);
+			tolua_function(tolua_S, "GetFurnaceRecipe",    tolua_cRoot_GetFurnaceRecipe);
 		tolua_endmodule(tolua_S);
 
-		tolua_beginmodule(tolua_S, "cPluginLua");
-			tolua_function(tolua_S, "AddWebTab", tolua_cPluginLua_AddWebTab);
+		tolua_beginmodule(tolua_S, "cScoreboard");
+			tolua_function(tolua_S, "ForEachObjective", ForEach);
+			tolua_function(tolua_S, "ForEachTeam",      ForEach);
 		tolua_endmodule(tolua_S);
 
-		tolua_cclass(tolua_S, "HTTPRequest", "HTTPRequest", "", nullptr);
-		tolua_beginmodule(tolua_S, "HTTPRequest");
-			// tolua_variable(tolua_S, "Method", tolua_get_HTTPRequest_Method, tolua_set_HTTPRequest_Method);
-			// tolua_variable(tolua_S, "Path", tolua_get_HTTPRequest_Path, tolua_set_HTTPRequest_Path);
-			tolua_variable(tolua_S, "FormData", tolua_get_HTTPRequest_FormData, 0);
-			tolua_variable(tolua_S, "Params", tolua_get_HTTPRequest_Params, 0);
-			tolua_variable(tolua_S, "PostParams", tolua_get_HTTPRequest_PostParams, 0);
+		tolua_beginmodule(tolua_S, "cStringCompression");
+			tolua_function(tolua_S, "CompressStringZLIB",     tolua_CompressStringZLIB);
+			tolua_function(tolua_S, "UncompressStringZLIB",   tolua_UncompressStringZLIB);
+			tolua_function(tolua_S, "CompressStringGZIP",     tolua_CompressStringGZIP);
+			tolua_function(tolua_S, "UncompressStringGZIP",   tolua_UncompressStringGZIP);
+			tolua_function(tolua_S, "InflateString",          tolua_InflateString);
 		tolua_endmodule(tolua_S);
 
 		tolua_beginmodule(tolua_S, "cWebAdmin");
@@ -3987,47 +2932,16 @@ void ManualBindings::Bind(lua_State * tolua_S)
 		tolua_beginmodule(tolua_S, "cWebPlugin");
 			tolua_function(tolua_S, "GetTabNames", tolua_cWebPlugin_GetTabNames);
 		tolua_endmodule(tolua_S);
-			
-		tolua_beginmodule(tolua_S, "cClientHandle");
-			tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE);
-			tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE);
-			tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage);
-		tolua_endmodule(tolua_S);
 
-		tolua_beginmodule(tolua_S, "cMojangAPI");
-			tolua_function(tolua_S, "AddPlayerNameToUUIDMapping", tolua_cMojangAPI_AddPlayerNameToUUIDMapping);
-			tolua_function(tolua_S, "GetPlayerNameFromUUID",      tolua_cMojangAPI_GetPlayerNameFromUUID);
-			tolua_function(tolua_S, "GetUUIDFromPlayerName",      tolua_cMojangAPI_GetUUIDFromPlayerName);
-			tolua_function(tolua_S, "GetUUIDsFromPlayerNames",    tolua_cMojangAPI_GetUUIDsFromPlayerNames);
-			tolua_function(tolua_S, "MakeUUIDDashed",             tolua_cMojangAPI_MakeUUIDDashed);
-			tolua_function(tolua_S, "MakeUUIDShort",              tolua_cMojangAPI_MakeUUIDShort);
-		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cItemGrid");
-			tolua_function(tolua_S, "GetSlotCoords", Lua_ItemGrid_GetSlotCoords);
+		tolua_beginmodule(tolua_S, "HTTPRequest");
+			tolua_variable(tolua_S, "FormData",   tolua_get_HTTPRequest_FormData,   nullptr);
+			tolua_variable(tolua_S, "Params",     tolua_get_HTTPRequest_Params,     nullptr);
+			tolua_variable(tolua_S, "PostParams", tolua_get_HTTPRequest_PostParams, nullptr);
 		tolua_endmodule(tolua_S);
 
-		tolua_beginmodule(tolua_S, "cCryptoHash");
-			tolua_function(tolua_S, "md5", tolua_md5);
-			tolua_function(tolua_S, "md5HexString", tolua_md5HexString);
-			tolua_function(tolua_S, "sha1", tolua_sha1);
-			tolua_function(tolua_S, "sha1HexString", tolua_sha1HexString);
-		tolua_endmodule(tolua_S);
-		
-		tolua_beginmodule(tolua_S, "cStringCompression");
-			tolua_function(tolua_S, "CompressStringZLIB",     tolua_CompressStringZLIB);
-			tolua_function(tolua_S, "UncompressStringZLIB",   tolua_UncompressStringZLIB);
-			tolua_function(tolua_S, "CompressStringGZIP",     tolua_CompressStringGZIP);
-			tolua_function(tolua_S, "UncompressStringGZIP",   tolua_UncompressStringGZIP);
-			tolua_function(tolua_S, "InflateString",          tolua_InflateString);
-		tolua_endmodule(tolua_S);
-		
-		BindRankManager(tolua_S);
 		BindNetwork(tolua_S);
-
-		tolua_beginmodule(tolua_S, "cEntity");
-			tolua_constant(tolua_S, "INVALID_ID", cEntity::INVALID_ID);
-		tolua_endmodule(tolua_S);
+		BindRankManager(tolua_S);
+		BindWorld(tolua_S);
 
 	tolua_endmodule(tolua_S);
 }
diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h
index 74d24d5f5..e7a576588 100644
--- a/src/Bindings/ManualBindings.h
+++ b/src/Bindings/ManualBindings.h
@@ -1,33 +1,566 @@
+
+// ManualBindings.h
+
+// Declares the cManualBindings class used as a namespace for functions exported to the Lua API manually
+
+
+
+
+
 #pragma once
 
-struct lua_State;
-class cPluginLua;
+#include "LuaState.h"
+
+
+
+
+// fwd:
+struct tolua_Error;
 
 
 
 
 
 /** Provides namespace for the bindings. */
-class ManualBindings
+class cManualBindings
 {
 public:
 	/** Binds all the manually implemented functions to tolua_S. */
 	static void Bind(lua_State * tolua_S);
 	
 protected:
+	/** Binds the manually implemented cNetwork-related API to tolua_S.
+	Implemented in ManualBindings_Network.cpp. */
+	static void BindNetwork(lua_State * tolua_S);
+
 	/** Binds the manually implemented cRankManager glue code to tolua_S.
 	Implemented in ManualBindings_RankManager.cpp. */
 	static void BindRankManager(lua_State * tolua_S);
 
-	/** Binds the manually implemented cNetwork-related API to tolua_S.
-	Implemented in ManualBindings_Network.cpp. */
-	static void BindNetwork(lua_State * tolua_S);
-};
+	/** Binds the manually implemented cWorld API functions to tolua_S.
+	Implemented in ManualBindings_World.cpp. */
+	static void BindWorld(lua_State * tolua_S);
+
+
+public:
+	// Helper functions:
+	static cPluginLua * GetLuaPlugin(lua_State * L);
+	static int tolua_do_error(lua_State * L, const char * a_pMsg, tolua_Error * a_pToLuaError);
+	static int lua_do_error(lua_State * L, const char * a_pFormat, ...);
+
+
+	/** Binds the DoWith(ItemName) functions of regular classes. */
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*DoWithFn)(const AString &, cItemCallback &)
+	>
+	static int DoWith(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamString(2) ||
+			!L.CheckParamFunction(3)
+		)
+		{
+			return 0;
+		}
+
+		// Get parameters:
+		Ty1 * Self;
+		AString ItemName;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, ItemName, FnRef);
+		if (Self == nullptr)
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+		}
+		if (ItemName.empty() || (ItemName[0] == 0))
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool ret = false;
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
+				return ret;
+			}
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+		} Callback(L, FnRef);
+
+		// Call the DoWith function:
+		bool res = (Self->*DoWithFn)(ItemName, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	/** Template for static functions DoWith(ItemName), on a type that has a static ::Get() function. */
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*DoWithFn)(const AString &, cItemCallback &)
+	>
+	static int StaticDoWith(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamString(2) ||
+			!L.CheckParamFunction(3)
+		)
+		{
+			return 0;
+		}
+
+		// Get parameters:
+		AString ItemName;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(2, ItemName, FnRef);
+		if (ItemName.empty() || (ItemName[0] == 0))
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool ret = false;
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
+				return ret;
+			}
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+		} Callback(L, FnRef);
+
+		// Call the DoWith function:
+		bool res = (Ty1::Get()->*DoWithFn)(ItemName, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*DoWithFn)(UInt32, cItemCallback &)
+	>
+	static int DoWithID(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamNumber(2) ||
+			!L.CheckParamFunction(3)
+		)
+		{
+			return 0;
+		}
+
+		// Get parameters:
+		Ty1 * Self = nullptr;
+		int ItemID;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, ItemID, FnRef);
+		if (Self == nullptr)
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool ret = false;
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
+				return ret;
+			}
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+		} Callback(L, FnRef);
+
+		// Call the DoWith function:
+		bool res = (Self->*DoWithFn)(ItemID, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
 
 
 
 
-extern cPluginLua * GetLuaPlugin(lua_State * L);
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*DoWithFn)(int, int, int, cItemCallback &)
+	>
+	static int DoWithXYZ(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamNumber(2, 5) ||
+			!L.CheckParamFunction(6)
+		)
+		{
+			return 0;
+		}
+
+		// Get parameters:
+		Ty1 * Self = nullptr;
+		int BlockX, BlockY, BlockZ;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, BlockX, BlockY, BlockZ, FnRef);
+		if (Self == nullptr)
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #5");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool ret = false;
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
+				return ret;
+			}
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+		} Callback(L, FnRef);
+
+		// Call the DoWith function:
+		bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*ForEachFn)(int, int, cItemCallback &)
+	>
+	static int ForEachInChunk(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamNumber(2, 4) ||
+			!L.CheckParamFunction(5)
+		)
+		{
+			return 0;
+		}
+
+		// Get parameters:
+		Ty1 * Self = nullptr;
+		int ChunkX, ChunkZ;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, ChunkX, ChunkZ, FnRef);
+		if (Self == nullptr)
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #4");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool ret = false;
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
+				return ret;
+			}
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+		} Callback(L, FnRef);
+
+		// Call the DoWith function:
+		bool res = (Self->*ForEachFn)(ChunkX, ChunkZ, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*ForEachFn)(const cBoundingBox &, cItemCallback &)
+	>
+	static int ForEachInBox(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamUserType(1, "cWorld") ||
+			!L.CheckParamUserType(2, "cBoundingBox") ||
+			!L.CheckParamFunction(3) ||
+			!L.CheckParamEnd(4)
+		)
+		{
+			return 0;
+		}
+
+		// Get the params:
+		Ty1 * Self = nullptr;
+		cBoundingBox * Box = nullptr;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, Box, FnRef);
+		if ((Self == nullptr) || (Box == nullptr))
+		{
+			LOGWARNING("Invalid world (%p) or boundingbox (%p)", Self, Box);
+			L.LogStackTrace();
+			return 0;
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
+		}
+
+		// Callback wrapper for the Lua function:
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) :
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FuncRef)
+			{
+			}
+
+		private:
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+
+			// cItemCallback overrides:
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool res = false;
+				if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res))
+				{
+					LOGWARNING("Failed to call Lua callback");
+					m_LuaState.LogStackTrace();
+					return true;  // Abort enumeration
+				}
+
+				return res;
+			}
+		} Callback(L, FnRef);
+
+		bool res = (Self->*ForEachFn)(*Box, Callback);
+
+		// Push the result as the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*ForEachFn)(cItemCallback &)
+	>
+	static int ForEach(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamFunction(2) ||
+			!L.CheckParamEnd(3)
+		)
+		{
+			return 0;
+		}
+
+		// Get the params:
+		Ty1 * Self = nullptr;
+		cLuaState::cRef FnRef;
+		L.GetStackValues(1, Self, FnRef);
+		if (Self == nullptr)
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'.");
+		}
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool res = false;  // By default continue the enumeration
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
+				return res;
+			}
+		} Callback(L, FnRef);
+
+		// Call the enumeration:
+		bool res = (Self->*ForEachFn)(Callback);
+
+		// Push the return value:
+		L.Push(res);
+		return 1;
+	}
+
+
+
+
+
+	/** Implements bindings for ForEach() functions in a class that is static (has a ::Get() static function). */
+	template <
+		class Ty1,
+		class Ty2,
+		bool (Ty1::*ForEachFn)(cItemCallback &)
+	>
+	static int StaticForEach(lua_State * tolua_S)
+	{
+		// Check params:
+		cLuaState L(tolua_S);
+		if (
+			!L.CheckParamFunction(2) ||
+			!L.CheckParamEnd(3)
+		)
+		{
+			return 0;
+		}
+
+		// Get the params:
+		cLuaState::cRef FnRef(L, 2);
+		if (!FnRef.IsValid())
+		{
+			return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
+		}
+
+		class cLuaCallback : public cItemCallback
+		{
+		public:
+			cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
+				m_LuaState(a_LuaState),
+				m_FnRef(a_FnRef)
+			{
+			}
+
+		private:
+			cLuaState & m_LuaState;
+			cLuaState::cRef & m_FnRef;
+
+			virtual bool Item(Ty2 * a_Item) override
+			{
+				bool res = false;  // By default continue the enumeration
+				m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
+				return res;
+			}
+		} Callback(L, FnRef);
+
+		// Call the enumeration:
+		bool res = (Ty1::Get()->*ForEachFn)(Callback);
+
+		// Push the return value:
+		L.Push(res);
+		return 1;
+	}
+};
 
 
 
diff --git a/src/Bindings/ManualBindings_Network.cpp b/src/Bindings/ManualBindings_Network.cpp
index 628cda7f0..df97d60b3 100644
--- a/src/Bindings/ManualBindings_Network.cpp
+++ b/src/Bindings/ManualBindings_Network.cpp
@@ -39,7 +39,7 @@ static int tolua_cNetwork_Connect(lua_State * L)
 	}
 	
 	// Get the plugin instance:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -92,7 +92,7 @@ static int tolua_cNetwork_CreateUDPEndpoint(lua_State * L)
 	}
 	
 	// Get the plugin instance:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -171,7 +171,7 @@ static int tolua_cNetwork_HostnameToIP(lua_State * L)
 	}
 	
 	// Get the plugin instance:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -212,7 +212,7 @@ static int tolua_cNetwork_IPToHostname(lua_State * L)
 	}
 	
 	// Get the plugin instance:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -253,7 +253,7 @@ static int tolua_cNetwork_Listen(lua_State * L)
 	}
 	
 	// Get the plugin instance:
-	cPluginLua * Plugin = GetLuaPlugin(L);
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
 	if (Plugin == nullptr)
 	{
 		// An error message has been already printed in GetLuaPlugin()
@@ -913,17 +913,17 @@ static int tolua_cUDPEndpoint_Send(lua_State * L)
 ////////////////////////////////////////////////////////////////////////////////
 // Register the bindings:
 
-void ManualBindings::BindNetwork(lua_State * tolua_S)
+void cManualBindings::BindNetwork(lua_State * tolua_S)
 {
 	// Create the cNetwork API classes:
 	tolua_usertype(tolua_S, "cNetwork");
-	tolua_cclass(tolua_S, "cNetwork", "cNetwork", "", nullptr);
-	tolua_usertype(tolua_S, "cTCPLink");
-	tolua_cclass(tolua_S, "cTCPLink", "cTCPLink", "", nullptr);
 	tolua_usertype(tolua_S, "cServerHandle");
-	tolua_cclass(tolua_S, "cServerHandle", "cServerHandle", "", tolua_collect_cServerHandle);
+	tolua_usertype(tolua_S, "cTCPLink");
 	tolua_usertype(tolua_S, "cUDPEndpoint");
-	tolua_cclass(tolua_S, "cUDPEndpoint", "cUDPEndpoint", "", tolua_collect_cUDPEndpoint);
+	tolua_cclass(tolua_S, "cNetwork",      "cNetwork",      "", nullptr);
+	tolua_cclass(tolua_S, "cServerHandle", "cServerHandle", "", tolua_collect_cServerHandle);
+	tolua_cclass(tolua_S, "cTCPLink",      "cTCPLink",      "", nullptr);
+	tolua_cclass(tolua_S, "cUDPEndpoint",  "cUDPEndpoint",  "", tolua_collect_cUDPEndpoint);
 	
 	// Fill in the functions (alpha-sorted):
 	tolua_beginmodule(tolua_S, "cNetwork");
diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp
index c9f187fc6..7797d1887 100644
--- a/src/Bindings/ManualBindings_RankManager.cpp
+++ b/src/Bindings/ManualBindings_RankManager.cpp
@@ -1280,7 +1280,7 @@ static int tolua_cRankManager_SetRankVisuals(lua_State * L)
 
 
 
-void ManualBindings::BindRankManager(lua_State * tolua_S)
+void cManualBindings::BindRankManager(lua_State * tolua_S)
 {
 	// Create the cRankManager class in the API:
 	tolua_usertype(tolua_S, "cRankManager");
diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp
new file mode 100644
index 000000000..3ee5ca498
--- /dev/null
+++ b/src/Bindings/ManualBindings_World.cpp
@@ -0,0 +1,588 @@
+
+// ManualBindings_World.cpp
+
+// Implements the manual Lua API bindings for the cWorld class
+
+#include "Globals.h"
+#include "tolua++/include/tolua++.h"
+#include "../World.h"
+#include "../Broadcaster.h"
+#include "ManualBindings.h"
+#include "LuaState.h"
+#include "PluginLua.h"
+#include "LuaChunkStay.h"
+
+
+
+
+
+static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S)
+{
+	/* Function signature:
+	World:BroadcastParticleEffect("Name", PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2]
+	*/
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamString  (2) ||
+		!L.CheckParamNumber  (3, 10)
+	)
+	{
+		return 0;
+	}
+	
+	// Read the params:
+	cWorld * World = nullptr;
+	AString Name;
+	float PosX, PosY, PosZ, OffX, OffY, OffZ;
+	float ParticleData;
+	int ParticleAmmount;
+	cClientHandle * ExcludeClient = nullptr;
+	L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmmount, ExcludeClient);
+	if (World == nullptr)
+	{
+		LOGWARNING("World:BroadcastParticleEffect(): invalid world parameter");
+		L.LogStackTrace();
+		return 0;
+	}
+
+	// Read up to 2 more optional data params:
+	std::array data;
+	for (int i = 0; (i < 2) && L.IsParamNumber(11 + i); i++)
+	{
+		L.GetStackValue(11 + i, data[i]);
+	}
+
+	World->GetBroadcaster().BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmmount, ExcludeClient);
+
+	return 0;
+}
+
+
+
+
+
+static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
+{
+	/* Function signature:
+	World:ChunkStay(ChunkCoordTable, OnChunkAvailable, OnAllChunksAvailable)
+	ChunkCoordTable == { {Chunk1x, Chunk1z}, {Chunk2x, Chunk2z}, ... }
+	*/
+	
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType     (1, "cWorld") ||
+		!L.CheckParamTable        (2) ||
+		!L.CheckParamFunctionOrNil(3, 4)
+	)
+	{
+		return 0;
+	}
+	
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
+	if (Plugin == nullptr)
+	{
+		return 0;
+	}
+	
+	// Read the params:
+	cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
+	if (World == nullptr)
+	{
+		LOGWARNING("World:ChunkStay(): invalid world parameter");
+		L.LogStackTrace();
+		return 0;
+	}
+
+	cLuaChunkStay * ChunkStay = new cLuaChunkStay(*Plugin);
+
+	if (!ChunkStay->AddChunks(2))
+	{
+		delete ChunkStay;
+		ChunkStay = nullptr;
+		return 0;
+	}
+
+	ChunkStay->Enable(*World->GetChunkMap(), 3, 4);
+	return 0;
+}
+
+
+
+
+
+static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S)
+{
+	// Exported manually, because tolua would generate useless additional parameters (a_BlockType .. a_BlockSkyLight)
+	// Function signature: GetBlockInfo(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta, BlockSkyLight, BlockBlockLight]
+
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber(2, 4) ||
+		!L.CheckParamEnd(5)
+	)
+	{
+		return 0;
+	}
+
+	// Get params:
+	cWorld * Self = nullptr;
+	int BlockX, BlockY, BlockZ;
+	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
+	if (Self == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+	}
+
+	// Call the function:
+	BLOCKTYPE BlockType;
+	NIBBLETYPE BlockMeta, BlockSkyLight, BlockBlockLight;
+	bool res = Self->GetBlockInfo(BlockX, BlockY, BlockZ, BlockType, BlockMeta, BlockSkyLight, BlockBlockLight);
+
+	// Push the returned values:
+	L.Push(res);
+	if (res)
+	{
+		L.Push(BlockType);
+		L.Push(BlockMeta);
+		L.Push(BlockSkyLight);
+		L.Push(BlockBlockLight);
+		return 5;
+	}
+	return 1;
+}
+
+
+
+
+
+static int tolua_cWorld_GetBlockTypeMeta(lua_State * tolua_S)
+{
+	// Exported manually, because tolua would generate useless additional parameters (a_BlockType, a_BlockMeta)
+	// Function signature: GetBlockTypeMeta(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta]
+
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber(2, 4) ||
+		!L.CheckParamEnd(5)
+	)
+	{
+		return 0;
+	}
+
+	// Get params:
+	cWorld * Self = nullptr;
+	int BlockX, BlockY, BlockZ;
+	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
+	if (Self == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+	}
+
+	// Call the function:
+	BLOCKTYPE BlockType;
+	NIBBLETYPE BlockMeta;
+	bool res = Self->GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockType, BlockMeta);
+
+	// Push the returned values:
+	L.Push(res);
+	if (res)
+	{
+		L.Push(BlockType);
+		L.Push(BlockMeta);
+		return 3;
+	}
+	return 1;
+}
+
+
+
+
+
+static int tolua_cWorld_GetSignLines(lua_State * tolua_S)
+{
+	// Exported manually, because tolua would generate useless additional parameters (a_Line1 .. a_Line4)
+
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber(2, 4) ||
+		!L.CheckParamEnd(5)
+	)
+	{
+		return 0;
+	}
+
+	// Get params:
+	cWorld * Self = nullptr;
+	int BlockX, BlockY, BlockZ;
+	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
+	if (Self == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+	}
+
+	// Call the function:
+	AString Line1, Line2, Line3, Line4;
+	bool res = Self->GetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
+
+	// Push the returned values:
+	L.Push(res);
+	if (res)
+	{
+		L.Push(Line1);
+		L.Push(Line2);
+		L.Push(Line3);
+		L.Push(Line4);
+		return 5;
+	}
+	return 1;
+}
+
+
+
+
+
+static int tolua_cWorld_PrepareChunk(lua_State * tolua_S)
+{
+	/* Function signature:
+	World:PrepareChunk(ChunkX, ChunkZ, Callback)
+	*/
+	
+	// Check the param types:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType     (1, "cWorld") ||
+		!L.CheckParamNumber       (2, 3) ||
+		!L.CheckParamFunctionOrNil(4)
+	)
+	{
+		return 0;
+	}
+	
+	// Read the params:
+	cWorld * world = nullptr;
+	int chunkX = 0, chunkZ = 0;
+	L.GetStackValues(1, world, chunkX, chunkZ);
+	if (world == nullptr)
+	{
+		LOGWARNING("World:PrepareChunk(): invalid world parameter");
+		L.LogStackTrace();
+		return 0;
+	}
+
+	// Wrap the Lua callback inside a C++ callback class:
+	class cCallback:
+		public cChunkCoordCallback
+	{
+	public:
+		cCallback(lua_State * a_LuaState):
+			m_LuaState(a_LuaState),
+			m_Callback(m_LuaState, 4)
+		{
+		}
+
+		// cChunkCoordCallback override:
+		virtual void Call(int a_CBChunkX, int a_CBChunkZ) override
+		{
+			if (m_Callback.IsValid())
+			{
+				m_LuaState.Call(m_Callback, a_CBChunkX, a_CBChunkZ);
+			}
+
+			// This is the last reference of this object, we must delete it so that it doesn't leak:
+			delete this;
+		}
+
+	protected:
+		cLuaState m_LuaState;
+		cLuaState::cRef m_Callback;
+	};
+	cCallback * callback = new cCallback(tolua_S);
+
+	// Call the chunk preparation:
+	world->PrepareChunk(chunkX, chunkZ, callback);
+	return 0;
+}
+
+
+
+
+
+class cLuaWorldTask :
+	public cWorld::cTask,
+	public cPluginLua::cResettable
+{
+public:
+	cLuaWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
+		cPluginLua::cResettable(a_Plugin),
+		m_FnRef(a_FnRef)
+	{
+	}
+
+protected:
+	int m_FnRef;
+	
+	// cWorld::cTask overrides:
+	virtual void Run(cWorld & a_World) override
+	{
+		cCSLock Lock(m_CSPlugin);
+		if (m_Plugin != nullptr)
+		{
+			m_Plugin->Call(m_FnRef, &a_World);
+		}
+	}
+} ;
+
+
+
+
+
+static int tolua_cWorld_QueueTask(lua_State * tolua_S)
+{
+	// Binding for cWorld::QueueTask
+	// Params: function
+	
+	// Retrieve the cPlugin from the LuaState:
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
+	if (Plugin == nullptr)
+	{
+		// An error message has been already printed in GetLuaPlugin()
+		return 0;
+	}
+
+	// Retrieve the args:
+	cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
+	if (self == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
+	}
+	if (!lua_isfunction(tolua_S, 2))
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #1");
+	}
+
+	// Create a reference to the function:
+	int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
+	if (FnRef == LUA_REFNIL)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
+	}
+
+	auto task = std::make_shared(*Plugin, FnRef);
+	Plugin->AddResettable(task);
+	self->QueueTask(task);
+	return 0;
+}
+
+
+
+
+
+static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
+{
+	// Exported manually, because tolua would generate useless additional return values (a_Line1 .. a_Line4)
+
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber(2, 4) ||
+		!L.CheckParamString(5, 8) ||
+		!L.CheckParamEnd(9)
+	)
+	{
+		return 0;
+	}
+
+	// Get params:
+	cWorld * Self = nullptr;
+	int BlockX, BlockY, BlockZ;
+	AString Line1, Line2, Line3, Line4;
+	L.GetStackValues(1, Self, BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
+	if (Self == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
+	}
+
+	// Call the function:
+	bool res = Self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
+
+	// Push the returned values:
+	L.Push(res);
+	return 1;
+}
+
+
+
+
+
+class cLuaScheduledWorldTask :
+	public cWorld::cTask,
+	public cPluginLua::cResettable
+{
+public:
+	cLuaScheduledWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
+		cPluginLua::cResettable(a_Plugin),
+		m_FnRef(a_FnRef)
+	{
+	}
+
+protected:
+	int m_FnRef;
+	
+	// cWorld::cTask overrides:
+	virtual void Run(cWorld & a_World) override
+	{
+		cCSLock Lock(m_CSPlugin);
+		if (m_Plugin != nullptr)
+		{
+			m_Plugin->Call(m_FnRef, &a_World);
+		}
+	}
+};
+
+
+
+
+
+static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
+{
+	// Binding for cWorld::ScheduleTask
+	// Params: function, Ticks
+	
+	// Retrieve the cPlugin from the LuaState:
+	cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
+	if (Plugin == nullptr)
+	{
+		// An error message has been already printed in GetLuaPlugin()
+		return 0;
+	}
+
+	// Retrieve the args:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber  (2) ||
+		!L.CheckParamFunction(3)
+	)
+	{
+		return 0;
+	}
+	cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
+	if (World == nullptr)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
+	}
+
+	// Create a reference to the function:
+	int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
+	if (FnRef == LUA_REFNIL)
+	{
+		return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
+	}
+	
+	int DelayTicks = (int)tolua_tonumber(tolua_S, 2, 0);
+
+	auto task = std::make_shared(*Plugin, FnRef);
+	Plugin->AddResettable(task);
+	World->ScheduleTask(DelayTicks, task);
+	return 0;
+}
+
+
+
+
+
+
+static int tolua_cWorld_TryGetHeight(lua_State * tolua_S)
+{
+	/* Exported manually, because tolua would require the out-only param a_Height to be used when calling
+	Function signature: world:TryGetHeight(a_World, a_BlockX, a_BlockZ) -> IsValid, Height
+	*/
+
+	// Check params:
+	cLuaState L(tolua_S);
+	if (
+		!L.CheckParamUserType(1, "cWorld") ||
+		!L.CheckParamNumber(2, 3) ||
+		!L.CheckParamEnd(4)
+	)
+	{
+		return 0;
+	}
+
+	// Get params:
+	cWorld * self = nullptr;
+	int BlockX, BlockZ;
+	L.GetStackValues(1, self, BlockX, BlockZ);
+	if (self == nullptr)
+	{
+		tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", nullptr);
+		return 0;
+	}
+
+	// Call the implementation:
+	int Height = 0;
+	bool res = self->TryGetHeight(BlockX, BlockZ, Height);
+	L.Push(res ? 1 : 0);
+	if (res)
+	{
+		L.Push(Height);
+		return 2;
+	}
+	return 1;
+}
+
+
+
+
+
+void cManualBindings::BindWorld(lua_State * tolua_S)
+{
+	tolua_beginmodule(tolua_S, nullptr);
+		tolua_beginmodule(tolua_S, "cWorld");
+			tolua_function(tolua_S, "BroadcastParticleEffect",   tolua_cWorld_BroadcastParticleEffect);
+			tolua_function(tolua_S, "ChunkStay",                 tolua_cWorld_ChunkStay);
+			tolua_function(tolua_S, "DoWithBlockEntityAt",       DoWithXYZ);
+			tolua_function(tolua_S, "DoWithBeaconAt",            DoWithXYZ);
+			tolua_function(tolua_S, "DoWithChestAt",             DoWithXYZ);
+			tolua_function(tolua_S, "DoWithDispenserAt",         DoWithXYZ);
+			tolua_function(tolua_S, "DoWithDropSpenserAt",       DoWithXYZ);
+			tolua_function(tolua_S, "DoWithDropperAt",           DoWithXYZ);
+			tolua_function(tolua_S, "DoWithEntityByID",          DoWithID< cWorld, cEntity,             &cWorld::DoWithEntityByID>);
+			tolua_function(tolua_S, "DoWithFurnaceAt",           DoWithXYZ);
+			tolua_function(tolua_S, "DoWithNoteBlockAt",         DoWithXYZ);
+			tolua_function(tolua_S, "DoWithCommandBlockAt",      DoWithXYZ);
+			tolua_function(tolua_S, "DoWithMobHeadAt",           DoWithXYZ);
+			tolua_function(tolua_S, "DoWithFlowerPotAt",         DoWithXYZ);
+			tolua_function(tolua_S, "DoWithPlayer",              DoWith<   cWorld, cPlayer,             &cWorld::DoWithPlayer>);
+			tolua_function(tolua_S, "FindAndDoWithPlayer",       DoWith<   cWorld, cPlayer,             &cWorld::FindAndDoWithPlayer>);
+			tolua_function(tolua_S, "DoWithPlayerByUUID",        DoWith<   cWorld, cPlayer,             &cWorld::DoWithPlayerByUUID>);
+			tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk);
+			tolua_function(tolua_S, "ForEachChestInChunk",       ForEachInChunk);
+			tolua_function(tolua_S, "ForEachEntity",             ForEach<       cWorld, cEntity,        &cWorld::ForEachEntity>);
+			tolua_function(tolua_S, "ForEachEntityInBox",        ForEachInBox<  cWorld, cEntity,        &cWorld::ForEachEntityInBox>);
+			tolua_function(tolua_S, "ForEachEntityInChunk",      ForEachInChunk);
+			tolua_function(tolua_S, "ForEachFurnaceInChunk",     ForEachInChunk);
+			tolua_function(tolua_S, "ForEachPlayer",             ForEach<       cWorld, cPlayer,        &cWorld::ForEachPlayer>);
+			tolua_function(tolua_S, "GetBlockInfo",              tolua_cWorld_GetBlockInfo);
+			tolua_function(tolua_S, "GetBlockTypeMeta",          tolua_cWorld_GetBlockTypeMeta);
+			tolua_function(tolua_S, "GetSignLines",              tolua_cWorld_GetSignLines);
+			tolua_function(tolua_S, "PrepareChunk",              tolua_cWorld_PrepareChunk);
+			tolua_function(tolua_S, "QueueTask",                 tolua_cWorld_QueueTask);
+			tolua_function(tolua_S, "ScheduleTask",              tolua_cWorld_ScheduleTask);
+			tolua_function(tolua_S, "SetSignLines",              tolua_cWorld_SetSignLines);
+			tolua_function(tolua_S, "TryGetHeight",              tolua_cWorld_TryGetHeight);
+		tolua_endmodule(tolua_S);
+	tolua_endmodule(tolua_S);
+}
+
+
+
+
-- 
cgit v1.2.3


From f36b00f4d496cb90c8c77d0e6ae570502f3199ae Mon Sep 17 00:00:00 2001
From: Mattes D 
Date: Wed, 13 May 2015 18:31:01 +0200
Subject: All in-game commands go through the OnExecuteCommand hook.

Everything that has a slash at the beginning, doesn't matter if it is a registered command or not.
---
 MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua | 7 +++----
 src/Bindings/PluginManager.cpp                      | 7 +++++++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua
index 79b7bb055..db7eb97d1 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnExecuteCommand.lua
@@ -16,10 +16,9 @@ return
 			If the command is in-game, the first parameter to the hook function is the {{cPlayer|player}} who's
 			executing the command. If the command comes from the server console, the first parameter is nil.

- The server calls this hook even for unregistered (unknown) console commands. However, it doesn't call - the hook for unregistered in-game commands, simply because there's no way to distinguish between a - command and a chat message. If a plugin needs to intercept unknown in-game commands, it should use the - {{OnChat|HOOK_CHAT}} hook. + The server calls this hook even for unregistered (unknown) console commands. It also calls the hook + for unknown in-game commands, as long as they begin with a slash ('/'). If a plugin needs to intercept + in-game chat messages not beginning with a slash, it should use the {{OnChat|HOOK_CHAT}} hook. ]], Params = { diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 15bea22bd..db2493955 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1445,6 +1445,13 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, if (cmd == m_Commands.end()) { // Command not found + // If it started with a slash, ask the plugins if they still want to handle it: + if (!a_Command.empty() && (a_Command[0] == '/')) + { + CommandResult Result = crUnknownCommand; + CallHookExecuteCommand(&a_Player, Split, a_Command, Result); + return Result; + } return crUnknownCommand; } -- cgit v1.2.3 From 2cdc2a16e4631c541f0b520f547621a23fe90baa Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 13 May 2015 18:45:29 +0200 Subject: Fixed chat message manipulation by plugins. Plugins, in their OnChat hook, can change the chat message sent by a player. --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 7117229f7..c8ccc1cf5 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1473,7 +1473,7 @@ void cClientHandle::HandleChat(const AString & a_Message) Color.clear(); } Msg.AddTextPart(AString("<") + m_Player->GetName() + "> ", Color); - Msg.ParseText(a_Message); + Msg.ParseText(Message); Msg.UnderlineUrls(); m_Player->GetWorld()->BroadcastChat(Msg); } -- cgit v1.2.3 From 394192bdaf6bc285be8258ead6553c3cb4054d2f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 13 May 2015 19:20:53 +0200 Subject: InfoDump: Added support for links. Also fixed processing of lists and list items. --- MCServer/Plugins/InfoDump.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index ab4dfd861..433827ce7 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -65,8 +65,12 @@ local function ForumizeString(a_Str) a_Str = a_Str:gsub("{%%p}", "\n\n") a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]") a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]") - a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]") - a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", "") + a_Str = a_Str:gsub("{%%list}", "\n[list]"):gsub("{%%/list}", "[/list]") + a_Str = a_Str:gsub("{%%li}", "\n[*]"):gsub("{%%/li}", "\n") + + -- Process links: {%a LinkDestination}LinkText{%/a} + a_Str = a_Str:gsub("{%%a%s([^}]*)}([^{]*){%%/a}", "[url=%1]%2[/url]") + -- TODO: Other formatting return a_Str @@ -106,8 +110,12 @@ local function GithubizeString(a_Str) a_Str = a_Str:gsub("{%%p}", "\n\n") a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**") a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*") - a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", "") - a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", "") + a_Str = a_Str:gsub("{%%list}", "\n"):gsub("{%%/list}", "\n") + a_Str = a_Str:gsub("{%%li}", "\n - "):gsub("{%%/li}", "") + + -- Process links: {%a LinkDestination}LinkText{%/a} + a_Str = a_Str:gsub("{%%a%s([^}]*)}([^{]*){%%/a}", "[%2](%1)") + -- TODO: Other formatting return a_Str -- cgit v1.2.3 From b34fd9c6d9a65987f3e0f55f33ddb03a89d8853f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 13 May 2015 19:24:57 +0200 Subject: InfoDump: Added DownloadLocation to forum post generator. --- MCServer/Plugins/InfoDump.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 433827ce7..a715c9a18 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -600,7 +600,10 @@ local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) DumpCommandsForum(a_PluginInfo, f) DumpPermissionsForum(a_PluginInfo, f) if (a_PluginInfo.SourceLocation ~= nil) then - f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]") + f:write("\n[b]Source[/b]: ", a_PluginInfo.SourceLocation, "\n") + end + if (a_PluginInfo.DownloadLocation ~= nil) then + f:write("[b]Download[/b]: ", a_PluginInfo.DownloadLocation) end f:close() return true -- cgit v1.2.3 From 8f0f421ae4affc20b5ee25979538d2ac240df213 Mon Sep 17 00:00:00 2001 From: Martin Fahy Date: Wed, 13 May 2015 23:05:44 -0400 Subject: Update World.cpp Fixed minor typos in comments, simply trying to understand the code base to fix issue regarding no sound when lighting is produced, no change to actual code. --- src/World.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 648c9cd19..c0a79b9d0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1019,7 +1019,7 @@ void cWorld::TickWeather(float a_Dt) // 0.5% chance per tick of thunderbolt if (m_TickRand.randInt() % 199 == 0) { - CastThunderbolt(0, 0, 0); // TODO: find random possitions near players to cast thunderbolts. + CastThunderbolt(0, 0, 0); // TODO: find random positions near players to cast thunderbolts. } } } @@ -1119,7 +1119,7 @@ void cWorld::TickScheduledTasks(void) auto WorldAge = m_WorldAge; // Move all the due tasks from m_ScheduledTasks into Tasks: - for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-basd for, we're modifying the container + for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-based for, we're modifying the container { if ((*itr)->m_TargetTick < std::chrono::duration_cast(WorldAge).count()) { -- cgit v1.2.3 From 67b6b71a5b82e18d4d08bd80f311afc18187bd8a Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 14 May 2015 16:49:13 +0200 Subject: Fixed possible crash in cProbabDistrib It could divide through 0 which causes a crash --- src/ProbabDistrib.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ProbabDistrib.cpp b/src/ProbabDistrib.cpp index c34c75982..ec3a4d85f 100644 --- a/src/ProbabDistrib.cpp +++ b/src/ProbabDistrib.cpp @@ -133,6 +133,7 @@ int cProbabDistrib::MapValue(int a_OrigValue) const // Linearly interpolate between Lo and Hi: int ProbDif = m_Cumulative[Hi].m_Probability - m_Cumulative[Lo].m_Probability; + ProbDif = (ProbDif != 0) ? ProbDif : 1; int ValueDif = m_Cumulative[Hi].m_Value - m_Cumulative[Lo].m_Value; return m_Cumulative[Lo].m_Value + (a_OrigValue - m_Cumulative[Lo].m_Probability) * ValueDif / ProbDif; } -- cgit v1.2.3 From 163aebf8ca95e4e5317318cf6e8ad14d53e0fde5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 14 May 2015 19:46:18 +0200 Subject: Fixed cPluginManager:ForEachCommand() and ForEachConsoleCommand() The functions would leak one value on the Lua stack for each enumerated command. Fixes #2017. --- src/Bindings/ManualBindings.cpp | 147 +++++++++++++++------------------------- 1 file changed, 54 insertions(+), 93 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 324ca9b89..ff904d74a 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -747,39 +747,38 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S) static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) { - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if (NumArgs != 1) - { - LOGWARN("Error in function call 'ForEachCommand': Requires 1 argument, got %i", NumArgs); - return 0; - } - - cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, nullptr); - if (self == nullptr) - { - LOGWARN("Error in function call 'ForEachCommand': Not called on an object instance"); - return 0; - } + /* + Function signature: + cPluginManager:Get():ForEachCommand(a_CallbackFn) -> bool + */ - if (!lua_isfunction(tolua_S, 2)) + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cPluginManager") || + !L.CheckParamFunction(2) || + !L.CheckParamEnd(3) + ) { - LOGWARN("Error in function call 'ForEachCommand': Expected a function for parameter #1"); return 0; } - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (FuncRef == LUA_REFNIL) + // Get the params: + cLuaState::cRef FnRef; + L.GetStackValues(2, FnRef); + if (!FnRef.IsValid()) { LOGWARN("Error in function call 'ForEachCommand': Could not get function reference of parameter #1"); return 0; } + // Callback for enumerating all commands: class cLuaCallback : public cPluginManager::cCommandEnumCallback { public: - cLuaCallback(lua_State * a_LuaState, int a_FuncRef): - LuaState(a_LuaState), - FuncRef(a_FuncRef) + cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef): + m_LuaState(a_LuaState), + m_FnRef(a_FnRef) { } @@ -787,35 +786,16 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) override { UNUSED(a_Plugin); - - lua_rawgeti(LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ - tolua_pushcppstring(LuaState, a_Command); - tolua_pushcppstring(LuaState, a_Permission); - tolua_pushcppstring(LuaState, a_HelpString); - - int s = lua_pcall(LuaState, 3, 1, 0); - if (cLuaState::ReportErrors(LuaState, s)) - { - return true; /* Abort enumeration */ - } - - if (lua_isboolean(LuaState, -1)) - { - return (tolua_toboolean(LuaState, -1, 0) > 0); - } - return false; /* Continue enumeration */ + bool ret = false; + m_LuaState.Call(m_FnRef, a_Command, a_Permission, a_HelpString, cLuaState::Return, ret); + return ret; } - lua_State * LuaState; - int FuncRef; - } Callback(tolua_S, FuncRef); + cLuaState & m_LuaState; + cLuaState::cRef & m_FnRef; + } Callback(L, FnRef); - bool bRetVal = self->ForEachCommand(Callback); - - /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ - luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); - - /* Push return value on stack */ - tolua_pushboolean(tolua_S, bRetVal); + // Execute and push the returned value: + L.Push(cPluginManager::Get()->ForEachCommand(Callback)); return 1; } @@ -825,39 +805,38 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) { - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if (NumArgs != 1) - { - LOGWARN("Error in function call 'ForEachConsoleCommand': Requires 1 argument, got %i", NumArgs); - return 0; - } - - cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, nullptr); - if (self == nullptr) - { - LOGWARN("Error in function call 'ForEachConsoleCommand': Not called on an object instance"); - return 0; - } + /* + Function signature: + cPluginManager:Get():ForEachConsoleCommand(a_CallbackFn) -> bool + */ - if (!lua_isfunction(tolua_S, 2)) + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cPluginManager") || + !L.CheckParamFunction(2) || + !L.CheckParamEnd(3) + ) { - LOGWARN("Error in function call 'ForEachConsoleCommand': Expected a function for parameter #1"); return 0; } - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (FuncRef == LUA_REFNIL) + // Get the params: + cLuaState::cRef FnRef; + L.GetStackValues(2, FnRef); + if (!FnRef.IsValid()) { LOGWARN("Error in function call 'ForEachConsoleCommand': Could not get function reference of parameter #1"); return 0; } + // Callback for enumerating all commands: class cLuaCallback : public cPluginManager::cCommandEnumCallback { public: - cLuaCallback(lua_State * a_LuaState, int a_FuncRef): - LuaState(a_LuaState), - FuncRef(a_FuncRef) + cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef): + m_LuaState(a_LuaState), + m_FnRef(a_FnRef) { } @@ -866,34 +845,16 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) { UNUSED(a_Plugin); UNUSED(a_Permission); - - lua_rawgeti(LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ - tolua_pushcppstring(LuaState, a_Command); - tolua_pushcppstring(LuaState, a_HelpString); - - int s = lua_pcall(LuaState, 2, 1, 0); - if (cLuaState::ReportErrors(LuaState, s)) - { - return true; /* Abort enumeration */ - } - - if (lua_isboolean(LuaState, -1)) - { - return (tolua_toboolean(LuaState, -1, 0) > 0); - } - return false; /* Continue enumeration */ + bool ret = false; + m_LuaState.Call(m_FnRef, a_Command, a_HelpString, cLuaState::Return, ret); + return ret; } - lua_State * LuaState; - int FuncRef; - } Callback(tolua_S, FuncRef); - - bool bRetVal = self->ForEachConsoleCommand(Callback); - - /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ - luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); + cLuaState & m_LuaState; + cLuaState::cRef & m_FnRef; + } Callback(L, FnRef); - /* Push return value on stack */ - tolua_pushboolean(tolua_S, bRetVal); + // Execute and push the returned value: + L.Push(cPluginManager::Get()->ForEachConsoleCommand(Callback)); return 1; } -- cgit v1.2.3 From f986f6d23d711d2caa2474b566ef7cddbc7aba69 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 15 May 2015 18:14:06 +0100 Subject: Removed tip4commit. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87c4ee93e..262ccc6d2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) +MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) ======== MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. -- cgit v1.2.3 From dd3c3f2574c175c3c73178ad48609e6547f460d9 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 15 May 2015 18:16:32 +0100 Subject: Unify shields. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 262ccc6d2..f9d34b842 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) +MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://img.shields.io/coverity/scan/1930.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) ======== MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. -- cgit v1.2.3 From a8878dd2b6cee69b7cc92b19c740cc4deb7c9735 Mon Sep 17 00:00:00 2001 From: SafwatHalaby Date: Fri, 15 May 2015 20:25:44 +0300 Subject: uniquePTR --- src/Mobs/Path.cpp | 9 ++------- src/Mobs/Path.h | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index ba7d615ae..dd306af13 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -215,11 +215,6 @@ bool cPath::Step_Internal() void cPath::FinishCalculation() { - for (auto && pair : m_Map) - { - delete pair.second; - } - m_Map.clear(); m_OpenList = std::priority_queue, compareHeuristics>{}; } @@ -348,7 +343,7 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) { Cell = new cPathCell(); Cell->m_Location = a_Location; - m_Map[a_Location] = Cell; + m_Map[a_Location] = UniquePtr(Cell); Cell->m_IsSolid = IsSolid(a_Location); Cell->m_Status = eCellStatus::NOLIST; #ifdef COMPILING_PATHFIND_DEBUGGER @@ -360,6 +355,6 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) } else { - return m_Map[a_Location]; + return m_Map[a_Location].get(); } } diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index adae77984..008722d29 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -131,7 +131,7 @@ private: /* Pathfinding fields */ std::priority_queue, compareHeuristics> m_OpenList; - std::unordered_map m_Map; + std::unordered_map, VectorHasher> m_Map; Vector3i m_Destination; Vector3i m_Source; int m_StepsLeft; -- cgit v1.2.3 From 5c3a85fba10e801c6553fa943fa85605bbcd4f41 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 15 May 2015 18:54:45 +0100 Subject: Revert "PathFinder - smart pointers" --- src/Mobs/Path.cpp | 9 +++++++-- src/Mobs/Path.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index dd306af13..ba7d615ae 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -215,6 +215,11 @@ bool cPath::Step_Internal() void cPath::FinishCalculation() { + for (auto && pair : m_Map) + { + delete pair.second; + } + m_Map.clear(); m_OpenList = std::priority_queue, compareHeuristics>{}; } @@ -343,7 +348,7 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) { Cell = new cPathCell(); Cell->m_Location = a_Location; - m_Map[a_Location] = UniquePtr(Cell); + m_Map[a_Location] = Cell; Cell->m_IsSolid = IsSolid(a_Location); Cell->m_Status = eCellStatus::NOLIST; #ifdef COMPILING_PATHFIND_DEBUGGER @@ -355,6 +360,6 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) } else { - return m_Map[a_Location].get(); + return m_Map[a_Location]; } } diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index 008722d29..adae77984 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -131,7 +131,7 @@ private: /* Pathfinding fields */ std::priority_queue, compareHeuristics> m_OpenList; - std::unordered_map, VectorHasher> m_Map; + std::unordered_map m_Map; Vector3i m_Destination; Vector3i m_Source; int m_StepsLeft; -- cgit v1.2.3 From 5a1be2620375b98f60bfd85a905ca963f0225801 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 15 May 2015 19:01:13 +0100 Subject: Newsletter, content tweak. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f9d34b842..3d013eff5 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://img.shields.io/coverity/scan/1930.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) ======== -MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. +MCServer is a Minecraft-compatible multiplayer game server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. MCServer is compatible with the vanilla Minecraft client. MCServer can run on Windows, *nix and Android operating systems. This includes Android phones and tablets as well as Raspberry Pis. We currently support Release 1.7 and 1.8 (not beta) Minecraft protocol versions. +Subscribe to [the newsletter](http://newsletter.cuberite.org/subscribe.htm) for important updates and project news. + Installation ------------ Hosted MCServer is available DIY on DigitalOcean: [![Install on DigitalOcean](http://doinstall.bearbin.net/button.svg)](http://doinstall.bearbin.net/install?url=https://github.com/mc-server/MCServer) and [Gamososm](https://gamocosm.com) also offers MCServer support. -- cgit v1.2.3 From 4ffc6621a9ca976f95eeda80e7c073ee932af85f Mon Sep 17 00:00:00 2001 From: SafwatHalaby Date: Fri, 15 May 2015 20:25:44 +0300 Subject: PathFinder uses UniquePtr for cell map. --- src/Mobs/Path.cpp | 9 ++------- src/Mobs/Path.h | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index ba7d615ae..dd306af13 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -215,11 +215,6 @@ bool cPath::Step_Internal() void cPath::FinishCalculation() { - for (auto && pair : m_Map) - { - delete pair.second; - } - m_Map.clear(); m_OpenList = std::priority_queue, compareHeuristics>{}; } @@ -348,7 +343,7 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) { Cell = new cPathCell(); Cell->m_Location = a_Location; - m_Map[a_Location] = Cell; + m_Map[a_Location] = UniquePtr(Cell); Cell->m_IsSolid = IsSolid(a_Location); Cell->m_Status = eCellStatus::NOLIST; #ifdef COMPILING_PATHFIND_DEBUGGER @@ -360,6 +355,6 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location) } else { - return m_Map[a_Location]; + return m_Map[a_Location].get(); } } diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index adae77984..008722d29 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -131,7 +131,7 @@ private: /* Pathfinding fields */ std::priority_queue, compareHeuristics> m_OpenList; - std::unordered_map m_Map; + std::unordered_map, VectorHasher> m_Map; Vector3i m_Destination; Vector3i m_Source; int m_StepsLeft; -- cgit v1.2.3 From da58620d45bf5d7d31f6d3700aa6687e17d0d1c8 Mon Sep 17 00:00:00 2001 From: tycho Date: Sat, 9 May 2015 13:16:07 +0100 Subject: Added TCLAP --- .gitmodules | 3 +++ lib/TCLAP | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/TCLAP diff --git a/.gitmodules b/.gitmodules index 93fac9d1f..20f8ea103 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "lib/libevent"] path = lib/libevent url = https://github.com/mc-server/libevent.git +[submodule "lib/TCLAP"] + path = lib/TCLAP + url = https://github.com/mc-server/TCLAP.git diff --git a/lib/TCLAP b/lib/TCLAP new file mode 160000 index 000000000..12cee3878 --- /dev/null +++ b/lib/TCLAP @@ -0,0 +1 @@ +Subproject commit 12cee38782897cfe60a1611615c200c45cd99eaf -- cgit v1.2.3 From b9efa02c80b54e044326771bbffdddf206daef2e Mon Sep 17 00:00:00 2001 From: tycho Date: Thu, 14 May 2015 15:47:51 +0100 Subject: Initial implementation of IniFile overloading --- src/Bindings/PluginManager.cpp | 38 +++-- src/Bindings/PluginManager.h | 11 +- src/CMakeLists.txt | 6 + src/Globals.h | 2 +- src/IniFile.cpp | 51 ++++-- src/IniFile.h | 26 +-- src/MemorySettingsRepository.cpp | 312 ++++++++++++++++++++++++++++++++++++ src/MemorySettingsRepository.h | 80 +++++++++ src/OverridesSettingsRepository.cpp | 273 +++++++++++++++++++++++++++++++ src/OverridesSettingsRepository.h | 52 ++++++ src/Protocol/Authenticator.cpp | 12 +- src/Protocol/Authenticator.h | 6 +- src/Protocol/MojangAPI.cpp | 10 +- src/Protocol/MojangAPI.h | 4 +- src/RCONServer.cpp | 8 +- src/RCONServer.h | 4 +- src/Root.cpp | 57 +++---- src/Root.h | 5 +- src/Server.cpp | 22 +-- src/Server.h | 4 +- src/SettingsRepositoryInterface.h | 46 ++++++ src/main.cpp | 42 ++++- 22 files changed, 955 insertions(+), 116 deletions(-) create mode 100644 src/MemorySettingsRepository.cpp create mode 100644 src/MemorySettingsRepository.h create mode 100644 src/OverridesSettingsRepository.cpp create mode 100644 src/OverridesSettingsRepository.h create mode 100644 src/SettingsRepositoryInterface.h diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index db2493955..86be30938 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -118,7 +118,7 @@ void cPluginManager::ReloadPluginsNow(void) -void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) +void cPluginManager::ReloadPluginsNow(cSettingsRepositoryInterface & a_Settings) { LOG("-- Loading Plugins --"); @@ -130,7 +130,7 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) RefreshPluginList(); // Load the plugins: - AStringVector ToLoad = GetFoldersToLoad(a_SettingsIni); + AStringVector ToLoad = GetFoldersToLoad(a_Settings); for (auto & pluginFolder: ToLoad) { LoadPlugin(pluginFolder); @@ -157,16 +157,16 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) -void cPluginManager::InsertDefaultPlugins(cIniFile & a_SettingsIni) +void cPluginManager::InsertDefaultPlugins(cSettingsRepositoryInterface & a_Settings) { - a_SettingsIni.AddKeyName("Plugins"); - a_SettingsIni.AddKeyComment("Plugins", " Plugin=Debuggers"); - a_SettingsIni.AddKeyComment("Plugins", " Plugin=HookNotify"); - a_SettingsIni.AddKeyComment("Plugins", " Plugin=ChunkWorx"); - a_SettingsIni.AddKeyComment("Plugins", " Plugin=APIDump"); - a_SettingsIni.AddValue("Plugins", "Plugin", "Core"); - a_SettingsIni.AddValue("Plugins", "Plugin", "TransAPI"); - a_SettingsIni.AddValue("Plugins", "Plugin", "ChatLog"); + a_Settings.AddKeyName("Plugins"); + a_Settings.AddKeyComment("Plugins", " Plugin=Debuggers"); + a_Settings.AddKeyComment("Plugins", " Plugin=HookNotify"); + a_Settings.AddKeyComment("Plugins", " Plugin=ChunkWorx"); + a_Settings.AddKeyComment("Plugins", " Plugin=APIDump"); + a_Settings.AddValue("Plugins", "Plugin", "Core"); + a_Settings.AddValue("Plugins", "Plugin", "TransAPI"); + a_Settings.AddValue("Plugins", "Plugin", "ChatLog"); } @@ -1896,25 +1896,23 @@ size_t cPluginManager::GetNumLoadedPlugins(void) const -AStringVector cPluginManager::GetFoldersToLoad(cIniFile & a_SettingsIni) +AStringVector cPluginManager::GetFoldersToLoad(cSettingsRepositoryInterface & a_Settings) { // Check if the Plugins section exists. - int KeyNum = a_SettingsIni.FindKey("Plugins"); - if (KeyNum == -1) + if (a_Settings.KeyExists("Plugins")) { - InsertDefaultPlugins(a_SettingsIni); - KeyNum = a_SettingsIni.FindKey("Plugins"); + InsertDefaultPlugins(a_Settings); } // Get the list of plugins to load: AStringVector res; - int NumPlugins = a_SettingsIni.GetNumValues(KeyNum); - for (int i = 0; i < NumPlugins; i++) + auto Values = a_Settings.GetValues("Plugins"); + for (auto NameValue : Values) { - AString ValueName = a_SettingsIni.GetValueName(KeyNum, i); + AString ValueName = NameValue.first; if (ValueName.compare("Plugin") == 0) { - AString PluginFile = a_SettingsIni.GetValue(KeyNum, i); + AString PluginFile = NameValue.second; if (!PluginFile.empty()) { res.push_back(PluginFile); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index d8c886b62..faabf3aec 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -24,6 +24,7 @@ class cPlayer; class cPlugin; class cProjectileEntity; class cWorld; +class cSettingsRepositoryInterface; struct TakeDamageInfo; typedef SharedPtr cPluginPtr; @@ -364,20 +365,20 @@ private: /** Reloads all plugins, defaulting to settings.ini for settings location */ void ReloadPluginsNow(void); - /** Reloads all plugins with a cIniFile object expected to be initialised to settings.ini */ - void ReloadPluginsNow(cIniFile & a_SettingsIni); + /** Reloads all plugins with a settings repo expected to be initialised to settings.ini */ + void ReloadPluginsNow(cSettingsRepositoryInterface & a_Settings); /** Unloads all plugins */ void UnloadPluginsNow(void); - /** Handles writing default plugins if 'Plugins' key not found using a cIniFile object expected to be intialised to settings.ini */ - void InsertDefaultPlugins(cIniFile & a_SettingsIni); + /** Handles writing default plugins if 'Plugins' key not found using a settings repo expected to be intialised to settings.ini */ + void InsertDefaultPlugins(cSettingsRepositoryInterface & a_Settings); /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ CommandResult HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); /** Returns the folders that are specified in the settings ini to load plugins from. */ - AStringVector GetFoldersToLoad(cIniFile & a_SettingsIni); + AStringVector GetFoldersToLoad(cSettingsRepositoryInterface & a_Settings); } ; // tolua_export diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e367bcf5..25de24c91 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,11 +48,13 @@ SET (SRCS Logger.cpp Map.cpp MapManager.cpp + MemorySettingsRepository.cpp MobCensus.cpp MobFamilyCollecter.cpp MobProximityCounter.cpp MobSpawner.cpp MonsterConfig.cpp + OverridesSettingsRepository.cpp ProbabDistrib.cpp RankManager.cpp RCONServer.cpp @@ -116,11 +118,13 @@ SET (HDRS Map.h MapManager.h Matrix4.h + MemorySettingsRepository.h MobCensus.h MobFamilyCollecter.h MobProximityCounter.h MobSpawner.h MonsterConfig.h + OverridesSettingsRepository.h ProbabDistrib.h RankManager.h RCONServer.h @@ -128,6 +132,7 @@ SET (HDRS Scoreboard.h Server.h SetChunkData.h + SettingsRepositoryInterface.h Statistics.h StringCompression.h StringUtils.h @@ -142,6 +147,7 @@ SET (HDRS include_directories(".") include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/sqlite") include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/SQLiteCpp/include") +include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/TCLAP/include") configure_file("BuildInfo.h.cmake" "${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.h") diff --git a/src/Globals.h b/src/Globals.h index 1f354ae77..cee2094bc 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -436,7 +436,7 @@ typename std::enable_if::value, C>::type CeilC(T a_Value) template std::unique_ptr make_unique(Args&&... args) { - return std::unique_ptr(new T(args...)); + return std::unique_ptr(new T(std::forward(args)...)); } // a tick is 50 ms diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 99c0a5f0f..8dab87d15 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -49,6 +49,9 @@ cIniFile::cIniFile(void) : bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect) { + + m_Filename = a_FileName; + // Normally you would use ifstream, but the SGI CC compiler has // a few bugs with ifstream. So ... fstream used. fstream f; @@ -56,7 +59,8 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect) AString keyname, valuename, value; AString::size_type pLeft, pRight; bool IsFromExampleRedirect = false; - + + f.open((FILE_IO_PREFIX + a_FileName).c_str(), ios::in); if (f.fail()) { @@ -650,7 +654,7 @@ void cIniFile::Clear(void) -bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName) +bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName) const { // Find the key: int keyID = FindKey(a_KeyName); @@ -889,8 +893,36 @@ void cIniFile::RemoveBom(AString & a_line) const +bool cIniFile::KeyExists(AString a_keyname) const +{ + return FindKey(a_keyname) != noID; +} + + + + + +std::vector> cIniFile::GetValues(AString a_keyName) +{ + std::vector> ret; + int keyID = FindKey(a_keyName); + if (keyID == noID) + { + return ret; + } + for (size_t valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + { + ret.emplace_back(keys[keyID].names[valueID], keys[keyID].values[valueID]); + } + return ret; +} + + + + + AStringVector ReadUpgradeIniPorts( - cIniFile & a_IniFile, + cSettingsRepositoryInterface & a_Settings, const AString & a_KeyName, const AString & a_PortsValueName, const AString & a_OldIPv4ValueName, @@ -899,23 +931,23 @@ AStringVector ReadUpgradeIniPorts( ) { // Read the regular value, but don't use the default (in order to detect missing value for upgrade): - AStringVector Ports = StringSplitAndTrim(a_IniFile.GetValue(a_KeyName, a_PortsValueName), ";,"); + AStringVector Ports = StringSplitAndTrim(a_Settings.GetValue(a_KeyName, a_PortsValueName), ";,"); if (Ports.empty()) { // Historically there were two separate entries for IPv4 and IPv6, merge them and migrate: - AString Ports4 = a_IniFile.GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue); - AString Ports6 = a_IniFile.GetValue(a_KeyName, a_OldIPv6ValueName); + AString Ports4 = a_Settings.GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue); + AString Ports6 = a_Settings.GetValue(a_KeyName, a_OldIPv6ValueName); Ports = MergeStringVectors(StringSplitAndTrim(Ports4, ";,"), StringSplitAndTrim(Ports6, ";,")); - a_IniFile.DeleteValue(a_KeyName, a_OldIPv4ValueName); - a_IniFile.DeleteValue(a_KeyName, a_OldIPv6ValueName); + a_Settings.DeleteValue(a_KeyName, a_OldIPv4ValueName); + a_Settings.DeleteValue(a_KeyName, a_OldIPv6ValueName); // If those weren't present or were empty, use the default:" if (Ports.empty()) { Ports = StringSplitAndTrim(a_DefaultValue, ";,"); } - a_IniFile.SetValue(a_KeyName, a_PortsValueName, StringsConcat(Ports, ',')); + a_Settings.SetValue(a_KeyName, a_PortsValueName, StringsConcat(Ports, ',')); } return Ports; @@ -923,4 +955,3 @@ AStringVector ReadUpgradeIniPorts( - diff --git a/src/IniFile.h b/src/IniFile.h index 71fea3a00..861be3800 100644 --- a/src/IniFile.h +++ b/src/IniFile.h @@ -18,7 +18,7 @@ #pragma once - +#include "SettingsRepositoryInterface.h" #define MAX_KEYNAME 128 #define MAX_VALUENAME 128 @@ -30,10 +30,12 @@ // tolua_begin -class cIniFile +class cIniFile : public cSettingsRepositoryInterface { private: bool m_IsCaseInsensitive; + + AString m_Filename; struct key { @@ -53,15 +55,19 @@ private: void RemoveBom(AString & a_line) const; public: - - enum errors - { - noID = -1, - }; /// Creates a new instance with no data cIniFile(void); +// tolua_end + virtual ~cIniFile() = default; + + virtual std::vector> GetValues(AString a_keyName) override; + + virtual bool KeyExists(const AString a_keyName) const override; + +// tolua_begin + // Sets whether or not keynames and valuenames should be case sensitive. // The default is case insensitive. void CaseSensitive (void) { m_IsCaseInsensitive = false; } @@ -77,11 +83,13 @@ public: /// Writes data stored in class to the specified ini file bool WriteFile(const AString & a_FileName) const; + virtual bool Flush() override { return WriteFile(m_Filename); } + /// Deletes all stored ini data (but doesn't touch the file) void Clear(void); /** Returns true iff the specified value exists. */ - bool HasValue(const AString & a_KeyName, const AString & a_ValueName); + bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const; /// Returns index of specified key, or noID if not found int FindKey(const AString & keyname) const; @@ -222,7 +230,7 @@ Reads the list of ports from a_PortsValueName. If that value doesn't exist or is in a_OldIPv4ValueName and a_OldIPv6ValueName; in this case the old values are removed from the INI file. If there is none of the three values or they are all empty, the default is used and stored in the Ports value. */ AStringVector ReadUpgradeIniPorts( - cIniFile & a_IniFile, + cSettingsRepositoryInterface & a_Settings, const AString & a_KeyName, const AString & a_PortsValueName, const AString & a_OldIPv4ValueName, diff --git a/src/MemorySettingsRepository.cpp b/src/MemorySettingsRepository.cpp new file mode 100644 index 000000000..21b4c769c --- /dev/null +++ b/src/MemorySettingsRepository.cpp @@ -0,0 +1,312 @@ + +#include "Globals.h" + +#include "MemorySettingsRepository.h" + + + + +bool cMemorySettingsRepository::KeyExists(const AString keyname) const +{ + return m_Map.count(keyname) != 0; +} + + + + + +bool cMemorySettingsRepository::HasValue(const AString & a_KeyName, const AString & a_ValueName) const +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + return false; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + return false; + } + return true; +} + + + + +int cMemorySettingsRepository::AddKeyName(const AString & a_keyname) +{ + m_Map.emplace(a_keyname, std::unordered_multimap{}); + return 0; +} + + + + + +bool cMemorySettingsRepository::AddKeyComment(const AString & keyname, const AString & comment) +{ + return false; +} + + + + + +AString cMemorySettingsRepository::GetKeyComment(const AString & keyname, const int commentID) const +{ + return ""; +} + + + + + +bool cMemorySettingsRepository::DeleteKeyComment(const AString & keyname, const int commentID) +{ + return false; +} + + + + + + +void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) +{ + if (m_Writable) + { + m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value)); + } +} + + + + +void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, Int64 a_Value) +{ + if (m_Writable) + { + m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value)); + } +} + + + + + +void cMemorySettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, bool a_Value) +{ + if (m_Writable) + { + m_Map[a_KeyName].emplace(a_ValueName, sValue(a_Value)); + } +} + + + + + +std::vector> cMemorySettingsRepository::GetValues(AString a_keyName) +{ + std::vector> ret; + for (auto pair : m_Map[a_keyName]) + { + ret.emplace_back(pair.first, pair.second.getStringValue()); + } + return ret; +} + + + + + +AString cMemorySettingsRepository::GetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) const +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + return defValue; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + return defValue; + } + return iter->second.getStringValue(); +} + + + + + +AString cMemorySettingsRepository::GetValueSet (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + return iter->second.getStringValue(); +} + + + + + +int cMemorySettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const int defValue) +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + AddValue(a_KeyName, a_ValueName, static_cast(defValue)); + return defValue; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + AddValue(a_KeyName, a_ValueName, static_cast(defValue)); + return defValue; + } + return static_cast(iter->second.getIntValue()); +} + + + + + +Int64 cMemorySettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const Int64 defValue) +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + return iter->second.getIntValue(); +} + + + + +bool cMemorySettingsRepository::GetValueSetB(const AString & a_KeyName, const AString & a_ValueName, const bool defValue) +{ + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + AddValue(a_KeyName, a_ValueName, defValue); + return defValue; + } + return iter->second.getBoolValue(); +} + + + + + +bool cMemorySettingsRepository::SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists) +{ + if (!m_Writable) + { + return false; + } + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + if (a_CreateIfNotExists) + { + AddValue(a_KeyName, a_ValueName, a_Value); + } + return a_CreateIfNotExists; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + if (a_CreateIfNotExists) + { + AddValue(a_KeyName, a_ValueName, a_Value); + } + return a_CreateIfNotExists; + } + iter->second = sValue(a_Value); + return true; +} + + + + +bool cMemorySettingsRepository::SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists) +{ + if (!m_Writable) + { + return false; + } + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + if (a_CreateIfNotExists) + { + AddValue(a_KeyName, a_ValueName, static_cast(a_Value)); + } + return a_CreateIfNotExists; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + if (a_CreateIfNotExists) + { + AddValue(a_KeyName, a_ValueName, static_cast(a_Value)); + } + return a_CreateIfNotExists; + } + iter->second = sValue(static_cast(a_Value)); + return true; +} + + + + + +bool cMemorySettingsRepository::DeleteValue(const AString & a_KeyName, const AString & a_ValueName) +{ + if (!m_Writable) + { + return false; + } + auto outerIter = m_Map.find(a_KeyName); + if (outerIter == m_Map.end()) + { + return false; + } + auto iter = outerIter->second.find(a_ValueName); + if (iter == outerIter->second.end()) + { + return false; + } + outerIter->second.erase(iter); + return true; +} + +bool cMemorySettingsRepository::Flush() +{ + return true; +} + diff --git a/src/MemorySettingsRepository.h b/src/MemorySettingsRepository.h new file mode 100644 index 000000000..335bc4513 --- /dev/null +++ b/src/MemorySettingsRepository.h @@ -0,0 +1,80 @@ + +#pragma once + +#include "SettingsRepositoryInterface.h" + +#include + +class cMemorySettingsRepository : public cSettingsRepositoryInterface +{ +public: + + virtual bool KeyExists(const AString keyname) const override; + + virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override; + + virtual int AddKeyName(const AString & keyname) override; + + virtual bool AddKeyComment(const AString & keyname, const AString & comment) override; + + virtual AString GetKeyComment(const AString & keyname, const int commentID) const override; + + virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override; + + virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) override; + void AddValue (const AString & a_KeyName, const AString & a_ValueName, const Int64 a_Value); + void AddValue (const AString & a_KeyName, const AString & a_ValueName, const bool a_Value); + + virtual std::vector> GetValues(AString a_keyName) override; + + virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const override; + + + virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override; + virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) override; + virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) override; + virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) override; + + virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) override; + virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) override; + + virtual bool DeleteValue(const AString & keyname, const AString & valuename) override; + + virtual bool Flush() override; + + void SetReadOnly() + { + m_Writable = false; + } + +private: + + bool m_Writable = true; + + struct sValue + { + sValue(AString value) : m_Type(eType::String), m_stringValue (value) {} + sValue(Int64 value) : m_Type(eType::Int64), m_intValue(value) {} + sValue(bool value) : m_Type(eType::Bool), m_boolValue(value) {} + + AString getStringValue() const { ASSERT(m_Type == eType::String); return m_stringValue; } + Int64 getIntValue() const { ASSERT(m_Type == eType::Int64); return m_intValue; } + bool getBoolValue() const { ASSERT(m_Type == eType::Bool); return m_boolValue; } + private: + enum class eType + { + String, + Int64, + Bool + } m_Type; + AString m_stringValue; + union + { + Int64 m_intValue; + bool m_boolValue; + }; + }; + + std::unordered_map> m_Map{}; +}; + diff --git a/src/OverridesSettingsRepository.cpp b/src/OverridesSettingsRepository.cpp new file mode 100644 index 000000000..6defdd6b5 --- /dev/null +++ b/src/OverridesSettingsRepository.cpp @@ -0,0 +1,273 @@ + +#include "Globals.h" +#include "OverridesSettingsRepository.h" + +cOverridesSettingsRepository::cOverridesSettingsRepository(std::unique_ptr a_Main, std::unique_ptr a_Overrides) : + m_Main(std::move(a_Main)), + m_Overrides(std::move(a_Overrides)) +{ +} + + + + + +bool cOverridesSettingsRepository::KeyExists(const AString a_keyName) const +{ + return m_Overrides->KeyExists(a_keyName) || m_Main->KeyExists(a_keyName); +} + + + + +bool cOverridesSettingsRepository::HasValue(const AString & a_KeyName, const AString & a_ValueName) const +{ + return m_Overrides->HasValue(a_KeyName, a_ValueName) || m_Main->HasValue(a_KeyName, a_ValueName); +} + + + + + +int cOverridesSettingsRepository::AddKeyName(const AString & a_keyname) +{ + + if (m_Overrides->KeyExists(a_keyname)) + { + m_Overrides->AddKeyName(a_keyname); + return 0; + } + + return m_Main->AddKeyName(a_keyname); +} + + + + + +bool cOverridesSettingsRepository::AddKeyComment(const AString & a_keyname, const AString & a_comment) +{ + if (m_Overrides->KeyExists(a_keyname)) + { + return m_Overrides->AddKeyComment(a_keyname, a_comment); + } + + return m_Main->AddKeyComment(a_keyname, a_comment); +} + + + + + +AString cOverridesSettingsRepository::GetKeyComment(const AString & a_keyname, const int a_commentID) const +{ + + if (m_Overrides->KeyExists(a_keyname)) + { + return m_Overrides->GetKeyComment(a_keyname, a_commentID); + } + + return m_Main->GetKeyComment(a_keyname, a_commentID); +} + + + + + +bool cOverridesSettingsRepository::DeleteKeyComment(const AString & a_keyname, const int a_commentID) +{ + if (m_Overrides->KeyExists(a_keyname)) + { + return m_Overrides->DeleteKeyComment(a_keyname, a_commentID); + } + + return m_Main->DeleteKeyComment(a_keyname, a_commentID); +} + + + + + +void cOverridesSettingsRepository::AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + m_Overrides->AddValue(a_KeyName, a_ValueName, a_Value); + } + else + { + m_Main->AddValue(a_KeyName, a_ValueName, a_Value); + } +} + + + + + +std::vector> cOverridesSettingsRepository::GetValues(AString a_keyName) +{ + auto overrides = m_Overrides->GetValues(a_keyName); + auto main = m_Main->GetValues(a_keyName); + std::sort(overrides.begin(), overrides.end(), [](std::pair a, std::pair b) -> bool { return a < b ;}); + std::sort(main.begin(), main.end(), [](std::pair a, std::pair b) -> bool { return a < b ;}); + + std::vector> ret; + + + size_t overridesIndex = 0; + for (auto pair : main) + { + if (overridesIndex >= overrides.size()) + { + ret.push_back(pair); + continue; + } + if (pair.first == overrides[overridesIndex].first) + { + continue; + } + while (pair.first > overrides[overridesIndex].first) + { + ret.push_back(overrides[overridesIndex]); + overridesIndex++; + } + ret.push_back(pair); + } + return ret; +} + + + + + +AString cOverridesSettingsRepository::GetValue(const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) const +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->GetValue(a_KeyName, a_ValueName, defValue); + } + else + { + return m_Main->GetValue(a_KeyName, a_ValueName, defValue); + } +} + + + + + +AString cOverridesSettingsRepository::GetValueSet (const AString & a_KeyName, const AString & a_ValueName, const AString & defValue) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->GetValueSet(a_KeyName, a_ValueName, defValue); + } + else + { + return m_Main->GetValueSet(a_KeyName, a_ValueName, defValue); + } +} + + + + + +int cOverridesSettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const int defValue) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->GetValueSetI(a_KeyName, a_ValueName, defValue); + } + else + { + return m_Main->GetValueSetI(a_KeyName, a_ValueName, defValue); + } +} + + + + + +Int64 cOverridesSettingsRepository::GetValueSetI(const AString & a_KeyName, const AString & a_ValueName, const Int64 defValue) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->GetValueSetI(a_KeyName, a_ValueName, defValue); + } + else + { + return m_Main->GetValueSetI(a_KeyName, a_ValueName, defValue); + } +} + + + + + +bool cOverridesSettingsRepository::GetValueSetB(const AString & a_KeyName, const AString & a_ValueName, const bool defValue) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->GetValueSetB(a_KeyName, a_ValueName, defValue); + } + else + { + return m_Main->GetValueSetB(a_KeyName, a_ValueName, defValue); + } +} + + + + + +bool cOverridesSettingsRepository::SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->SetValue(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists); + } + else + { + return m_Main->SetValue(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists); + } +} + + + + + +bool cOverridesSettingsRepository::SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->SetValueI(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists); + } + else + { + return m_Main->SetValueI(a_KeyName, a_ValueName, a_Value, a_CreateIfNotExists); + } +} + + + + + +bool cOverridesSettingsRepository::DeleteValue(const AString & a_KeyName, const AString & a_ValueName) +{ + if (m_Overrides->HasValue(a_KeyName, a_ValueName)) + { + return m_Overrides->DeleteValue(a_KeyName, a_ValueName); + } + else + { + return m_Overrides->DeleteValue(a_KeyName, a_ValueName); + } +} + + + +bool cOverridesSettingsRepository::Flush() +{ + return m_Overrides->Flush() && m_Main->Flush(); +} + diff --git a/src/OverridesSettingsRepository.h b/src/OverridesSettingsRepository.h new file mode 100644 index 000000000..04a53997f --- /dev/null +++ b/src/OverridesSettingsRepository.h @@ -0,0 +1,52 @@ + +#pragma once + +#include "SettingsRepositoryInterface.h" + +#include + +class cOverridesSettingsRepository : public cSettingsRepositoryInterface +{ + +public: + cOverridesSettingsRepository(std::unique_ptr a_Main, std::unique_ptr a_Overrides); + + virtual ~cOverridesSettingsRepository() = default; + + virtual bool KeyExists(const AString keyname) const override; + + virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override; + + virtual int AddKeyName(const AString & keyname) override; + + virtual bool AddKeyComment(const AString & keyname, const AString & comment) override; + + virtual AString GetKeyComment(const AString & keyname, const int commentID) const override; + + virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override; + + virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) override; + + virtual std::vector> GetValues(AString a_keyName) override; + + virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const override; + + virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override; + virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) override; + virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) override; + virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) override; + + virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) override; + virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) override; + + virtual bool DeleteValue(const AString & keyname, const AString & valuename) override; + + virtual bool Flush() override; + +private: + + std::unique_ptr m_Main; + std::unique_ptr m_Overrides; + +}; + diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index c9e4296a2..294b6e9be 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -40,11 +40,11 @@ cAuthenticator::~cAuthenticator() -void cAuthenticator::ReadINI(cIniFile & IniFile) +void cAuthenticator::ReadSettings(cSettingsRepositoryInterface & a_Settings) { - m_Server = IniFile.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER); - m_Address = IniFile.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS); - m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); + m_Server = a_Settings.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER); + m_Address = a_Settings.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS); + m_ShouldAuthenticate = a_Settings.GetValueSetB("Authentication", "Authenticate", true); } @@ -69,9 +69,9 @@ void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, co -void cAuthenticator::Start(cIniFile & IniFile) +void cAuthenticator::Start(cSettingsRepositoryInterface & a_Settings) { - ReadINI(IniFile); + ReadSettings(a_Settings); m_ShouldTerminate = false; super::Start(); } diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 853eff535..02b349256 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -14,7 +14,7 @@ #include "../OSSupport/IsThread.h" - +class cSettingsRepositoryInterface; @@ -40,13 +40,13 @@ public: ~cAuthenticator(); /** (Re-)read server and address from INI: */ - void ReadINI(cIniFile & IniFile); + void ReadSettings(cSettingsRepositoryInterface & a_Settings); /** Queues a request for authenticating a user. If the auth fails, the user will be kicked */ void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash); /** Starts the authenticator thread. The thread may be started and stopped repeatedly */ - void Start(cIniFile & IniFile); + void Start(cSettingsRepositoryInterface & a_Settings); /** Stops the authenticator thread. The thread may be started and stopped repeatedly */ void Stop(void); diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 0d1441500..51b8e90e7 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -226,12 +226,12 @@ cMojangAPI::~cMojangAPI() -void cMojangAPI::Start(cIniFile & a_SettingsIni, bool a_ShouldAuth) +void cMojangAPI::Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth) { - m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); - m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); - m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER); - m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS); + m_NameToUUIDServer = a_Settings.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); + m_NameToUUIDAddress = a_Settings.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); + m_UUIDToProfileServer = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER); + m_UUIDToProfileAddress = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS); LoadCachesFromDisk(); if (a_ShouldAuth) { diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 0dc2617b6..bea950740 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -25,7 +25,7 @@ namespace Json - +class cSettingsRepositoryInterface; // tolua_begin class cMojangAPI @@ -38,7 +38,7 @@ public: /** Initializes the API; reads the settings from the specified ini file. Loads cached results from disk. */ - void Start(cIniFile & a_SettingsIni, bool a_ShouldAuth); + void Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth); /** Connects to the specified server using SSL, sends the given request and receives the response. Checks Mojang certificates using the hard-coded Starfield root CA certificate. diff --git a/src/RCONServer.cpp b/src/RCONServer.cpp index 685bd92f5..c5dc9b69b 100644 --- a/src/RCONServer.cpp +++ b/src/RCONServer.cpp @@ -134,15 +134,15 @@ cRCONServer::~cRCONServer() -void cRCONServer::Initialize(cIniFile & a_IniFile) +void cRCONServer::Initialize(cSettingsRepositoryInterface & a_Settings) { - if (!a_IniFile.GetValueSetB("RCON", "Enabled", false)) + if (!a_Settings.GetValueSetB("RCON", "Enabled", false)) { return; } // Read the password, don't allow an empty one: - m_Password = a_IniFile.GetValueSet("RCON", "Password", ""); + m_Password = a_Settings.GetValueSet("RCON", "Password", ""); if (m_Password.empty()) { LOGWARNING("RCON is requested, but the password is not set. RCON is now disabled."); @@ -150,7 +150,7 @@ void cRCONServer::Initialize(cIniFile & a_IniFile) } // Read the listening ports for RCON from config: - AStringVector Ports = ReadUpgradeIniPorts(a_IniFile, "RCON", "Ports", "PortsIPv4", "PortsIPv6", "25575"); + AStringVector Ports = ReadUpgradeIniPorts(a_Settings, "RCON", "Ports", "PortsIPv4", "PortsIPv6", "25575"); // Start listening on each specified port: for (auto port: Ports) diff --git a/src/RCONServer.h b/src/RCONServer.h index 352fa7b50..81b019516 100644 --- a/src/RCONServer.h +++ b/src/RCONServer.h @@ -17,7 +17,7 @@ // fwd: class cServer; -class cIniFile; +class cSettingsRepositoryInterface; @@ -29,7 +29,7 @@ public: cRCONServer(cServer & a_Server); virtual ~cRCONServer(); - void Initialize(cIniFile & a_IniFile); + void Initialize(cSettingsRepositoryInterface & a_Settings); protected: friend class cRCONCommandOutput; diff --git a/src/Root.cpp b/src/Root.cpp index 349608e8d..de53e0cd8 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -19,6 +19,8 @@ #include "LoggerListeners.h" #include "BuildInfo.h" #include "IniFile.h" +#include "SettingsRepositoryInterface.h" +#include "OverridesSettingsRepository.h" #ifdef _WIN32 #include @@ -96,7 +98,7 @@ void cRoot::InputThread(cRoot & a_Params) -void cRoot::Start(void) +void cRoot::Start(std::unique_ptr overridesRepo) { #ifdef _WIN32 HWND hwnd = GetConsoleWindow(); @@ -130,22 +132,24 @@ void cRoot::Start(void) m_Server = new cServer(); LOG("Reading server config..."); - cIniFile IniFile; - if (!IniFile.ReadFile("settings.ini")) + + auto IniFile = make_unique(); + if (!IniFile->ReadFile("settings.ini")) { LOGWARN("Regenerating settings.ini, all settings will be reset"); - IniFile.AddHeaderComment(" This is the main server configuration"); - IniFile.AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); - IniFile.AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); + IniFile->AddHeaderComment(" This is the main server configuration"); + IniFile->AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); + IniFile->AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); } + auto settingsRepo = make_unique(std::move(IniFile), std::move(overridesRepo)); LOG("Starting server..."); m_MojangAPI = new cMojangAPI; - bool ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); - m_MojangAPI->Start(IniFile, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init - if (!m_Server->InitServer(IniFile, ShouldAuthenticate)) + bool ShouldAuthenticate = settingsRepo->GetValueSetB("Authentication", "Authenticate", true); + m_MojangAPI->Start(*settingsRepo, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init + if (!m_Server->InitServer(*settingsRepo, ShouldAuthenticate)) { - IniFile.WriteFile("settings.ini"); + settingsRepo->Flush(); LOGERROR("Failure starting server, aborting..."); return; } @@ -160,29 +164,29 @@ void cRoot::Start(void) m_FurnaceRecipe = new cFurnaceRecipe(); LOGD("Loading worlds..."); - LoadWorlds(IniFile); + LoadWorlds(*settingsRepo); LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); - m_PluginManager->ReloadPluginsNow(IniFile); + m_PluginManager->ReloadPluginsNow(*settingsRepo); LOGD("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; // This sets stuff in motion LOGD("Starting Authenticator..."); - m_Authenticator.Start(IniFile); + m_Authenticator.Start(*settingsRepo); LOGD("Starting worlds..."); StartWorlds(); - if (IniFile.GetValueSetB("DeadlockDetect", "Enabled", true)) + if (settingsRepo->GetValueSetB("DeadlockDetect", "Enabled", true)) { LOGD("Starting deadlock detector..."); - dd.Start(IniFile.GetValueSetI("DeadlockDetect", "IntervalSec", 20)); + dd.Start(settingsRepo->GetValueSetI("DeadlockDetect", "IntervalSec", 20)); } - IniFile.WriteFile("settings.ini"); + settingsRepo->Flush(); LOGD("Finalising startup..."); if (m_Server->Start()) @@ -282,30 +286,29 @@ void cRoot::LoadGlobalSettings() -void cRoot::LoadWorlds(cIniFile & IniFile) +void cRoot::LoadWorlds(cSettingsRepositoryInterface & a_Settings) { // First get the default world - AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); + AString DefaultWorldName = a_Settings.GetValueSet("Worlds", "DefaultWorld", "world"); m_pDefaultWorld = new cWorld(DefaultWorldName.c_str()); m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; // Then load the other worlds - int KeyNum = IniFile.FindKey("Worlds"); - int NumWorlds = IniFile.GetNumValues(KeyNum); - if (NumWorlds <= 0) + auto Worlds = a_Settings.GetValues("Worlds"); + if (Worlds.size() <= 0) { return; } bool FoundAdditionalWorlds = false; - for (int i = 0; i < NumWorlds; i++) + for (auto WorldNameValue : Worlds) { - AString ValueName = IniFile.GetValueName(KeyNum, i); + AString ValueName = WorldNameValue.first; if (ValueName.compare("World") != 0) { continue; } - AString WorldName = IniFile.GetValue(KeyNum, i); + AString WorldName = WorldNameValue.second; if (WorldName.empty()) { continue; @@ -317,10 +320,10 @@ void cRoot::LoadWorlds(cIniFile & IniFile) if (!FoundAdditionalWorlds) { - if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") + if (a_Settings.GetKeyComment("Worlds", 0) != " World=secondworld") { - IniFile.DeleteKeyComment("Worlds", 0); - IniFile.AddKeyComment("Worlds", " World=secondworld"); + a_Settings.DeleteKeyComment("Worlds", 0); + a_Settings.AddKeyComment("Worlds", " World=secondworld"); } } } diff --git a/src/Root.h b/src/Root.h index e0b6cf26c..2b30afaff 100644 --- a/src/Root.h +++ b/src/Root.h @@ -24,6 +24,7 @@ class cWorld; class cPlayer; class cCommandOutputCallback; class cCompositeChat; +class cSettingsRepositoryInterface; typedef cItemCallback cPlayerListCallback; typedef cItemCallback cWorldListCallback; @@ -53,7 +54,7 @@ public: cRoot(void); ~cRoot(); - void Start(void); + void Start(std::unique_ptr overridesRepo); // tolua_begin cServer * GetServer(void) { return m_Server; } @@ -204,7 +205,7 @@ private: void LoadGlobalSettings(); /// Loads the worlds from settings.ini, creates the worldmap - void LoadWorlds(cIniFile & IniFile); + void LoadWorlds(cSettingsRepositoryInterface & a_Settings); /// Starts each world's life void StartWorlds(void); diff --git a/src/Server.cpp b/src/Server.cpp index 996de2695..01d5a176a 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -185,12 +185,12 @@ void cServer::PlayerDestroying(const cPlayer * a_Player) -bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth) +bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth) { - m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!"); - m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100); - m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false); - m_bAllowMultiLogin = a_SettingsIni.GetValueSetB("Server", "AllowMultiLogin", false); + m_Description = a_Settings.GetValueSet("Server", "Description", "MCServer - in C++!"); + m_MaxPlayers = a_Settings.GetValueSetI("Server", "MaxPlayers", 100); + m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false); + m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false); m_PlayerCount = 0; m_PlayerCountDiff = 0; @@ -205,9 +205,9 @@ bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth) LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS); LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS); - m_Ports = ReadUpgradeIniPorts(a_SettingsIni, "Server", "Ports", "Port", "PortsIPv6", "25565"); + m_Ports = ReadUpgradeIniPorts(a_Settings, "Server", "Ports", "Port", "PortsIPv6", "25565"); - m_RCONServer.Initialize(a_SettingsIni); + m_RCONServer.Initialize(a_Settings); m_bIsConnected = true; @@ -226,16 +226,16 @@ bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth) } // Check if both BungeeCord and online mode are on, if so, warn the admin: - m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false); + m_ShouldAllowBungeeCord = a_Settings.GetValueSetB("Authentication", "AllowBungeeCord", false); if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate) { LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini."); } - m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false); - m_ShouldLoadNamedPlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true); + m_ShouldLoadOfflinePlayerData = a_Settings.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false); + m_ShouldLoadNamedPlayerData = a_Settings.GetValueSetB("PlayerData", "LoadNamedPlayerData", true); - m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); + m_ClientViewDistance = a_Settings.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) { m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; diff --git a/src/Server.h b/src/Server.h index 1f30295b7..4d0bc1c18 100644 --- a/src/Server.h +++ b/src/Server.h @@ -38,8 +38,8 @@ class cClientHandle; typedef SharedPtr cClientHandlePtr; typedef std::list cClientHandlePtrs; typedef std::list cClientHandles; -class cIniFile; class cCommandOutputCallback; +class cSettingsRepositoryInterface; namespace Json @@ -58,7 +58,7 @@ public: // tolua_end virtual ~cServer() {} - bool InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth); + bool InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth); // tolua_begin diff --git a/src/SettingsRepositoryInterface.h b/src/SettingsRepositoryInterface.h new file mode 100644 index 000000000..775a0be47 --- /dev/null +++ b/src/SettingsRepositoryInterface.h @@ -0,0 +1,46 @@ + +#pragma once + +class cSettingsRepositoryInterface +{ +public: + + enum errors + { + noID = -1, + }; + + virtual ~cSettingsRepositoryInterface() = default; + + virtual bool KeyExists(const AString keyname) const = 0; + + virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const = 0; + + virtual int AddKeyName(const AString & keyname) = 0; + + virtual bool AddKeyComment(const AString & keyname, const AString & comment) = 0; + + virtual AString GetKeyComment(const AString & keyname, const int commentID) const = 0; + + virtual bool DeleteKeyComment(const AString & keyname, const int commentID) = 0; + + virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) = 0; + + virtual std::vector> GetValues(AString a_keyName) = 0; + + virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const = 0; + + virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") = 0; + virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) = 0; + virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) = 0; + virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) = 0; + + virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) = 0; + virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) = 0; + + + virtual bool DeleteValue(const AString & keyname, const AString & valuename) = 0; + + + virtual bool Flush() = 0; +}; diff --git a/src/main.cpp b/src/main.cpp index 1c34b8f61..d37ff0b32 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Root.h" +#include "tclap/CmdLine.h" #include #include @@ -14,7 +15,7 @@ #include "OSSupport/NetworkSingleton.h" #include "BuildInfo.h" - +#include "MemorySettingsRepository.h" @@ -206,7 +207,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType) //////////////////////////////////////////////////////////////////////////////// // universalMain - Main startup logic for both standard running and as a service -void universalMain() +void universalMain(std::unique_ptr overridesRepo) { #ifdef _WIN32 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) @@ -226,7 +227,7 @@ void universalMain() #endif { cRoot Root; - Root.Start(); + Root.Start(std::move(overridesRepo)); } #if !defined(ANDROID_NDK) catch (std::exception & e) @@ -363,14 +364,39 @@ void WINAPI serviceMain(DWORD argc, TCHAR *argv[]) +std::unique_ptr parseArguments(int argc, char **argv) +{ + try + { + TCLAP::CmdLine cmd("MCServer"); + + TCLAP::ValueArg slotsArg("s", "max-players", "Maximum number of slots for the server to use, overrides setting in setting.ini", false, -1, "number", cmd); + + cmd.parse(argc, argv); + + int slots = slotsArg.getValue(); + + auto repo = make_unique(); + + repo->SetValueI("Server", "MaxPlayers", slots); + + repo->SetReadOnly(); + + return repo; + } + catch (TCLAP::ArgException &e) + { + printf("error reading command line %s for arg %s", e.error().c_str(), e.argId().c_str()); + return nullptr; + } +} + //////////////////////////////////////////////////////////////////////////////// // main: -int main( int argc, char **argv) +int main(int argc, char **argv) { - UNUSED(argc); - UNUSED(argv); #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) InitLeakFinder(); @@ -425,6 +451,8 @@ int main( int argc, char **argv) // DEBUG: test the dumpfile creation: // *((int *)0) = 0; + auto argsRepo = parseArguments(argc, argv); + // Check if comm logging is to be enabled: for (int i = 0; i < argc; i++) { @@ -483,7 +511,7 @@ int main( int argc, char **argv) #endif { // Not running as a service, do normal startup - universalMain(); + universalMain(std::move(argsRepo)); } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) -- cgit v1.2.3 From c96849f431bb4152a4258d2480bef8cd272e0c6e Mon Sep 17 00:00:00 2001 From: tycho Date: Fri, 15 May 2015 13:57:27 +0100 Subject: Move make_unique into a namespace to avoid ADL issues this prevents VS finding std::make_unique for constructors that take types from std --- src/Globals.h | 10 +++++++--- src/Root.cpp | 4 ++-- src/World.cpp | 10 +++++----- src/main.cpp | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index cee2094bc..27d944fcc 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -433,10 +433,14 @@ typename std::enable_if::value, C>::type CeilC(T a_Value) //temporary replacement for std::make_unique until we get c++14 -template -std::unique_ptr make_unique(Args&&... args) + +namespace cpp14 { - return std::unique_ptr(new T(std::forward(args)...)); + template + std::unique_ptr make_unique(Args&&... args) + { + return std::unique_ptr(new T(std::forward(args)...)); + } } // a tick is 50 ms diff --git a/src/Root.cpp b/src/Root.cpp index de53e0cd8..c3c880e73 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -133,7 +133,7 @@ void cRoot::Start(std::unique_ptr overridesRepo) LOG("Reading server config..."); - auto IniFile = make_unique(); + auto IniFile = cpp14::make_unique(); if (!IniFile->ReadFile("settings.ini")) { LOGWARN("Regenerating settings.ini, all settings will be reset"); @@ -141,7 +141,7 @@ void cRoot::Start(std::unique_ptr overridesRepo) IniFile->AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); IniFile->AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); } - auto settingsRepo = make_unique(std::move(IniFile), std::move(overridesRepo)); + auto settingsRepo = cpp14::make_unique(std::move(IniFile), std::move(overridesRepo)); LOG("Starting server..."); m_MojangAPI = new cMojangAPI; diff --git a/src/World.cpp b/src/World.cpp index c0a79b9d0..eb8835467 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -621,18 +621,18 @@ void cWorld::Start(void) InitialiseAndLoadMobSpawningValues(IniFile); SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay())); - m_ChunkMap = make_unique(this); + m_ChunkMap = cpp14::make_unique(this); // preallocate some memory for ticking blocks so we don't need to allocate that often m_BlockTickQueue.reserve(1000); m_BlockTickQueueCopy.reserve(1000); // Simulators: - m_SimulatorManager = make_unique(*this); + m_SimulatorManager = cpp14::make_unique(*this); m_WaterSimulator = InitializeFluidSimulator(IniFile, "Water", E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); m_LavaSimulator = InitializeFluidSimulator(IniFile, "Lava", E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); - m_SandSimulator = make_unique(*this, IniFile); - m_FireSimulator = make_unique(*this, IniFile); + m_SandSimulator = cpp14::make_unique(*this, IniFile); + m_FireSimulator = cpp14::make_unique(*this, IniFile); m_RedstoneSimulator = InitializeRedstoneSimulator(IniFile); // Water, Lava and Redstone simulators get registered in their initialize function. @@ -2680,7 +2680,7 @@ void cWorld::UnloadUnusedChunks(void) void cWorld::QueueUnloadUnusedChunks(void) { - QueueTask(make_unique()); + QueueTask(cpp14::make_unique()); } diff --git a/src/main.cpp b/src/main.cpp index d37ff0b32..9f57ad6bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -376,7 +376,7 @@ std::unique_ptr parseArguments(int argc, char **argv) int slots = slotsArg.getValue(); - auto repo = make_unique(); + auto repo = cpp14::make_unique(); repo->SetValueI("Server", "MaxPlayers", slots); -- cgit v1.2.3 From 0da8c7392e753b89b20dc0678e78ab3060e535ed Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 15 May 2015 14:54:48 +0100 Subject: Fix service Main --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9f57ad6bd..a0f51105a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -258,7 +258,7 @@ DWORD WINAPI serviceWorkerThread(LPVOID lpParam) UNREFERENCED_PARAMETER(lpParam); // Do the normal startup - universalMain(); + universalMain(cpp14::make_unique()); return ERROR_SUCCESS; } -- cgit v1.2.3 From 6350e4f279fa1d9cfe9436ccf209608543716471 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 16 May 2015 00:47:58 +0100 Subject: Bed uses bottom two bits for direction not three --- src/Blocks/BlockBed.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index e56f4bfe0..dfa392d9b 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -14,7 +14,7 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); Vector3i ThisPos( a_BlockX, a_BlockY, a_BlockZ); - Vector3i Direction = MetaDataToDirection( OldMeta & 0x7); + Vector3i Direction = MetaDataToDirection( OldMeta & 0x3); if (OldMeta & 0x8) { // Was pillow @@ -111,7 +111,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface // Is foot end VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken - PillowDirection = MetaDataToDirection(Meta & 0x7); + PillowDirection = MetaDataToDirection(Meta & 0x3); if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping { a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z); -- cgit v1.2.3 From 36fe8ee5f5ef9ed3641be34311d9d0a2259afd68 Mon Sep 17 00:00:00 2001 From: tycho Date: Sat, 16 May 2015 12:46:43 +0100 Subject: Added deoxy comments --- src/SettingsRepositoryInterface.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/SettingsRepositoryInterface.h b/src/SettingsRepositoryInterface.h index 775a0be47..443b90ff5 100644 --- a/src/SettingsRepositoryInterface.h +++ b/src/SettingsRepositoryInterface.h @@ -12,35 +12,50 @@ public: virtual ~cSettingsRepositoryInterface() = default; + /** Returns true iff the specified key exists */ virtual bool KeyExists(const AString keyname) const = 0; + /** Returns true iff the specified value exists. */ virtual bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const = 0; + /** Add a key name. Return value is not required to mean anything **/ virtual int AddKeyName(const AString & keyname) = 0; + /** Add a key comment, will always fail if the repository does not support comments **/ virtual bool AddKeyComment(const AString & keyname, const AString & comment) = 0; + /** Return a key comment, returns "" for repositories that do not return comments **/ virtual AString GetKeyComment(const AString & keyname, const int commentID) const = 0; + /** Delete a key comment, will always fail if the repository does not support comments **/ virtual bool DeleteKeyComment(const AString & keyname, const int commentID) = 0; + /** Adds a new value to the specified key. + If a value of the same name already exists, creates another one **/ virtual void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) = 0; + /** returns a vector containing a name, value pair for each value under the key **/ virtual std::vector> GetValues(AString a_keyName) = 0; + /** Get the value at the specified key and value, returns defValue on failure **/ virtual AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const = 0; + /** Gets the value; if not found, write the default to the repository **/ virtual AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") = 0; virtual int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) = 0; virtual Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) = 0; virtual bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) = 0; + /** Overwrites the value of the key, value pair + Specify the optional parameter as false if you do not want the value created if it doesn't exist. + Returns true if value set, false otherwise. **/ virtual bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) = 0; virtual bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) = 0; - + /** Deletes the specified key, value pair **/ virtual bool DeleteValue(const AString & keyname, const AString & valuename) = 0; + /** Writes the changes to the backing store, if the repository has one **/ virtual bool Flush() = 0; }; -- cgit v1.2.3 From 1240c76cb472931253e2ce502356c0428f974c5a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 16 May 2015 16:19:18 +0200 Subject: Lua: Break into ZBS debugger on API errors. --- src/Bindings/LuaState.cpp | 26 ++++++++++++++++++++++++++ src/Bindings/LuaState.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index ccf812417..08c7e19d7 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -927,6 +927,9 @@ bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); + + BreakIntoDebugger(m_LuaState); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -1366,6 +1369,7 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) { LOGWARNING("LUA: %s", lua_tostring(a_LuaState, -1)); LogStackTrace(a_LuaState, 1); + BreakIntoDebugger(a_LuaState); return 1; // We left the error message on the stack as the return value } @@ -1373,6 +1377,28 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) +int cLuaState::BreakIntoDebugger(lua_State * a_LuaState) +{ + // Call the BreakIntoDebugger function, if available: + lua_getglobal(a_LuaState, "BreakIntoDebugger"); + if (!lua_isfunction(a_LuaState, -1)) + { + LOGD("LUA: BreakIntoDebugger() not found / not a function"); + lua_pop(a_LuaState, 1); + return 1; + } + lua_insert(a_LuaState, -2); // Copy the string that has been passed to us + LOGD("Calling BreakIntoDebugger()..."); + lua_call(a_LuaState, 1, 0); + LOGD("Returned from BreakIntoDebugger()."); + + return 0; +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cLuaState::cRef: diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index b38401fd8..5b4ec3ae4 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -389,6 +389,9 @@ protected: /** Used as the error reporting function for function calls */ static int ReportFnCallErrors(lua_State * a_LuaState); + + /** Tries to break into the MobDebug debugger, if it is installed. */ + static int BreakIntoDebugger(lua_State * a_LuaState); } ; -- cgit v1.2.3 From f3d6da29f7916c4659351fe36049a47a7b90717b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 16 May 2015 23:22:50 +0200 Subject: Fixed inventory handling. Fixes #2035. --- src/Protocol/Protocol18x.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 17faca27e..4612af4a5 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -51,7 +51,7 @@ Implements the 1.8.x protocol classes: /** The slot number that the client uses to indicate "outside the window". */ -static const Int16 SLOT_NUM_OUTSIDE = -1; +static const Int16 SLOT_NUM_OUTSIDE = -999; @@ -2265,7 +2265,7 @@ void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffe { return; } - m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutside : caLeftClick); + m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == -1) ? caLeftClickOutside : caLeftClick); } -- cgit v1.2.3 From a22f0795f61108e06e1b7efef7681f314b3ea1a1 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 17 May 2015 09:32:56 +0100 Subject: Should disable coveralls. --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2fd3bf991..6dde5b62b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: cpp compiler: clang before_install: - - if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi +# - if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi # g++4.8 - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test @@ -21,17 +21,17 @@ install: # Build MCServer script: ./CIbuild.sh -after_success: - - ./uploadCoverage.sh +#after_success: +# - ./uploadCoverage.sh env: - TRAVIS_MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer - TRAVIS_MCSERVER_BUILD_TYPE=DEBUG MCSERVER_PATH=./MCServer_debug -matrix: - include: - - compiler: gcc - env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer +#matrix: +# include: +# - compiler: gcc +# env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer # Notification Settings notifications: -- cgit v1.2.3 From c94134ec5e8ad6ca98a7b375ef6d5848041b4a48 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 17 May 2015 10:53:16 +0100 Subject: Fix FastRandom seeding Fixes #1815 Fixes #2021 --- src/FastRandom.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index 737b13535..639aa65f0 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -6,12 +6,28 @@ #include "Globals.h" #include "FastRandom.h" +#include + #ifdef _WIN32 - #define thread_local __declspec(thread) + #define thread_local static __declspec(thread) +#elseif __OSX__ + #define thread_local static __thread #endif -thread_local unsigned int m_Counter = 0; - +static unsigned int GetRandomSeed() +{ + thread_local bool SeedCounterInitialized = 0; + thread_local unsigned int SeedCounter = 0; + + if (!SeedCounterInitialized) + { + std::random_device rd; + std::uniform_int_distribution dist; + SeedCounter = dist(rd); + SeedCounterInitialized = true; + } + return ++SeedCounter; +} @@ -92,7 +108,7 @@ public: cFastRandom::cFastRandom(void) : - m_LinearRand(m_Counter++) + m_LinearRand(GetRandomSeed()) { } @@ -136,7 +152,7 @@ int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End) // MTRand: MTRand::MTRand() : - m_MersenneRand(m_Counter++) + m_MersenneRand(GetRandomSeed()) { } -- cgit v1.2.3 From d48825fa815225a9529cea1a8b0e1aa64681587b Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 17 May 2015 14:23:16 +0100 Subject: Fix sapling probability. Probability is 5% of leaves drop a sapling. This should really be different for jungle leaves (2.5%) and the Fortune enchantment should increase the probability. --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index bd9a7414e..8e44c94ac 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -41,7 +41,7 @@ public: cFastRandom rand; // Old leaves - 3 bits contain display; new leaves - 1st bit, shifted left two for saplings to understand - if (rand.NextInt(6) == 0) + if (rand.NextInt(20) == 0) { a_Pickups.push_back( cItem( -- cgit v1.2.3 From adecdc2f07f7c0812eab665d5991f32ce0d6aa63 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 17 May 2015 16:10:55 +0100 Subject: Fixed typo. --- src/FastRandom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index 639aa65f0..437dc72ff 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -10,7 +10,7 @@ #ifdef _WIN32 #define thread_local static __declspec(thread) -#elseif __OSX__ +#elif __APPLE__ #define thread_local static __thread #endif -- cgit v1.2.3 From 1049d5b706d4e6c29ff9f9960bca3add2c0fd817 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 17 May 2015 16:30:13 +0100 Subject: properly this time? --- src/FastRandom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index 437dc72ff..c1716f026 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -10,7 +10,7 @@ #ifdef _WIN32 #define thread_local static __declspec(thread) -#elif __APPLE__ +#elif defined __APPLE__ #define thread_local static __thread #endif -- cgit v1.2.3 From 29e31c5be95abd6a7122a525f53d80f4576e49b2 Mon Sep 17 00:00:00 2001 From: SafwatHalaby Date: Sat, 16 May 2015 14:05:33 +0300 Subject: Pathfinder - approximated paths when original destination unreachable --- src/Mobs/AggressiveMonster.cpp | 1 - src/Mobs/Monster.cpp | 121 ++++++++++++++++++++++++++++++++--------- src/Mobs/Monster.h | 7 +++ src/Mobs/Path.cpp | 98 +++++++++++++++++++++++++-------- src/Mobs/Path.h | 21 ++++++- 5 files changed, 193 insertions(+), 55 deletions(-) diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index d0fb79f6d..055ff47d2 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -36,7 +36,6 @@ void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt) return; } } - MoveToPosition(m_Target->GetPosition()); } } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index f3f8c6b24..a29d67d15 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -89,7 +89,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A , m_SoundDeath(a_SoundDeath) , m_AttackRate(3) , m_AttackDamage(1) - , m_AttackRange(2) + , m_AttackRange(1) , m_AttackInterval(0) , m_SightDistance(25) , m_DropChanceWeapon(0.085f) @@ -147,10 +147,15 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) (Recalculate lots when close, calculate rarely when far) */ if ( ((GetPosition() - m_PathFinderDestination).Length() < 0.25) || - ((m_TicksSinceLastPathReset > 10) && (m_TicksSinceLastPathReset > (0.15 * (m_FinalDestination - GetPosition()).SqrLength()))) + ((m_TicksSinceLastPathReset > 10) && (m_TicksSinceLastPathReset > (0.4 * (m_FinalDestination - GetPosition()).SqrLength()))) ) { - ResetPathFinding(); + /* Re-calculating is expensive when there's no path to target, and it results in mobs freezing very often as a result of always recalculating. + This is a workaround till we get better path recalculation. */ + if (!m_NoPathToTarget) + { + ResetPathFinding(); + } } } @@ -161,12 +166,21 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) StopMovingToPosition(); // Invalid chunks, probably world is loading or something, cancel movement. return false; } + m_NoPathToTarget = false; + m_NoMoreWayPoints = false; m_PathFinderDestination = m_FinalDestination; m_Path = new cPath(a_Chunk, GetPosition().Floor(), m_PathFinderDestination.Floor(), 20); } switch (m_Path->Step(a_Chunk)) { + case ePathFinderStatus::NEARBY_FOUND: + { + m_NoPathToTarget = true; + m_Path->AcceptNearbyPath(); + break; + } + case ePathFinderStatus::PATH_NOT_FOUND: { StopMovingToPosition(); // Give up pathfinding to that destination. @@ -179,15 +193,22 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) } case ePathFinderStatus::PATH_FOUND: { - if (--m_GiveUpCounter == 0) + if (m_NoMoreWayPoints || (--m_GiveUpCounter == 0)) { ResetPathFinding(); // Try to calculate a path again. return false; } - else if (!m_Path->IsLastPoint() && (m_Path->IsFirstPoint() || ReachedNextWaypoint())) // Have we arrived at the next cell, as denoted by m_NextWayPointPosition? + else if (!m_Path->IsLastPoint()) // Have we arrived at the next cell, as denoted by m_NextWayPointPosition? + { + if ((m_Path->IsFirstPoint() || ReachedNextWaypoint())) + { + m_NextWayPointPosition = Vector3d(0.5, 0, 0.5) + m_Path->GetNextPoint(); + m_GiveUpCounter = 40; // Give up after 40 ticks (2 seconds) if failed to reach m_NextWayPointPosition. + } + } + else { - m_NextWayPointPosition = Vector3d(0.5, 0, 0.5) + m_Path->GetNextPoint(); - m_GiveUpCounter = 40; // Give up after 40 ticks (2 seconds) if failed to reach m_NextWayPointPosition. + m_NoMoreWayPoints = true; } return true; } @@ -269,21 +290,59 @@ bool cMonster::EnsureProperDestination(cChunk & a_Chunk) { return false; } - + int RelX = FloorC(m_FinalDestination.x) - Chunk->GetPosX() * cChunkDef::Width; int RelZ = FloorC(m_FinalDestination.z) - Chunk->GetPosZ() * cChunkDef::Width; - // If destination in the air, go down to the lowest air block. - while (m_FinalDestination.y > 0) + // If destination in the air, first try to go 1 block north, or east, or west. + // This fixes the player leaning issue. + // If that failed, we instead go down to the lowest air block. + Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y) - 1, RelZ, BlockType, BlockMeta); + if (!cBlockInfo::IsSolid(BlockType)) { - Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y) - 1, RelZ, BlockType, BlockMeta); - if (cBlockInfo::IsSolid(BlockType)) + bool InTheAir = true; + int x, z; + for (z = -1; z <= 1; ++z) { - break; + for (x = -1; x <= 1; ++x) + { + if ((x==0) && (z==0)) + { + continue; + } + Chunk = a_Chunk.GetNeighborChunk(FloorC(m_FinalDestination.x+x), FloorC(m_FinalDestination.z+z)); + if ((Chunk == nullptr) || !Chunk->IsValid()) + { + return false; + } + RelX = FloorC(m_FinalDestination.x+x) - Chunk->GetPosX() * cChunkDef::Width; + RelZ = FloorC(m_FinalDestination.z+z) - Chunk->GetPosZ() * cChunkDef::Width; + Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y) - 1, RelZ, BlockType, BlockMeta); + if (cBlockInfo::IsSolid(BlockType)) + { + m_FinalDestination.x += x; + m_FinalDestination.z += z; + InTheAir = false; + goto breakBothLoops; + } + } } - m_FinalDestination.y -= 1; - } + breakBothLoops: + // Go down to the lowest air block. + if (InTheAir) + { + while (m_FinalDestination.y > 0) + { + Chunk->GetBlockTypeMeta(RelX, FloorC(m_FinalDestination.y) - 1, RelZ, BlockType, BlockMeta); + if (cBlockInfo::IsSolid(BlockType)) + { + break; + } + m_FinalDestination.y -= 1; + } + } + } // If destination in water, go up to the highest water block. // If destination in solid, go up to first air block. @@ -447,21 +506,29 @@ void cMonster::SetPitchAndYawFromDestination() } } + + + Vector3d BodyDistance = m_NextWayPointPosition - GetPosition(); + double BodyRotation, BodyPitch; + BodyDistance.Normalize(); + VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch); + SetYaw(BodyRotation); + Vector3d Distance = FinalDestination - GetPosition(); { - double Rotation, Pitch; + double HeadRotation, HeadPitch; Distance.Normalize(); - VectorToEuler(Distance.x, Distance.y, Distance.z, Rotation, Pitch); - SetHeadYaw(Rotation); - SetPitch(-Pitch); - } - - { - Vector3d BodyDistance = m_NextWayPointPosition - GetPosition(); - double Rotation, Pitch; - BodyDistance.Normalize(); - VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, Rotation, Pitch); - SetYaw(Rotation); + VectorToEuler(Distance.x, Distance.y, Distance.z, HeadRotation, HeadPitch); + if (abs(BodyRotation - HeadRotation) < 120) + { + SetHeadYaw(HeadRotation); + SetPitch(-HeadPitch); + } + else // We're not an owl. If it's more than 120, don't look behind and instead look at where you're walking. + { + SetHeadYaw(BodyRotation); + SetPitch(-BodyPitch); + } } } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 5d20ba810..c4043b0e5 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -180,6 +180,13 @@ protected: /** Coordinates for the ultimate, final destination last given to the pathfinder. */ Vector3d m_PathFinderDestination; + /** True if there's no path to target and we're walking to an approximated location. */ + bool m_NoPathToTarget; + + /** Whether The mob has finished their path, note that this does not imply reaching the destination, + the destination may sometimes differ from the current path. */ + bool m_NoMoreWayPoints; + /** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does) If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 If current Y is solid, goes up to find first nonsolid block, and returns that. diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index dd306af13..ba8046a2b 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -8,7 +8,7 @@ #define DISTANCE_MANHATTAN 0 // 1: More speed, a bit less accuracy 0: Max accuracy, less speed. #define HEURISTICS_ONLY 0 // 1: Much more speed, much less accurate. -#define CALCULATIONS_PER_STEP 5 // Higher means more CPU load but faster path calculations. +#define CALCULATIONS_PER_STEP 10 // Higher means more CPU load but faster path calculations. // The only version which guarantees the shortest path is 0, 0. enum class eCellStatus {OPENLIST, CLOSEDLIST, NOLIST}; @@ -44,7 +44,8 @@ cPath::cPath( m_Destination(a_EndingPoint.Floor()), m_Source(a_StartingPoint.Floor()), m_CurrentPoint(0), // GetNextPoint increments this to 1, but that's fine, since the first cell is always a_StartingPoint - m_Chunk(&a_Chunk) + m_Chunk(&a_Chunk), + m_BadChunkFound(false) { // TODO: if src not walkable OR dest not walkable, then abort. // Borrow a new "isWalkable" from ProcessIfWalkable, make ProcessIfWalkable also call isWalkable @@ -55,6 +56,7 @@ cPath::cPath( return; } + m_NearestPointToTarget = GetCell(m_Source); m_Status = ePathFinderStatus::CALCULATING; m_StepsLeft = a_MaxSteps; @@ -81,15 +83,20 @@ cPath::~cPath() ePathFinderStatus cPath::Step(cChunk & a_Chunk) { m_Chunk = &a_Chunk; - if (m_Status != ePathFinderStatus::CALCULATING) { return m_Status; } - if (m_StepsLeft == 0) + if (m_BadChunkFound) { FinishCalculation(ePathFinderStatus::PATH_NOT_FOUND); + return m_Status; + } + + if (m_StepsLeft == 0) + { + AttemptToFindAlternative(); } else { @@ -102,9 +109,9 @@ ePathFinderStatus cPath::Step(cChunk & a_Chunk) break; // if we're here, m_Status must have changed either to PATH_FOUND or PATH_NOT_FOUND. } } - } - m_Chunk = nullptr; + m_Chunk = nullptr; + } return m_Status; } @@ -112,6 +119,17 @@ ePathFinderStatus cPath::Step(cChunk & a_Chunk) +Vector3i cPath::AcceptNearbyPath() +{ + ASSERT(m_Status == ePathFinderStatus::NEARBY_FOUND); + m_Status = ePathFinderStatus::PATH_FOUND; + return m_Destination; +} + + + + + bool cPath::IsSolid(const Vector3i & a_Location) { ASSERT(m_Chunk != nullptr); @@ -119,6 +137,7 @@ bool cPath::IsSolid(const Vector3i & a_Location) auto Chunk = m_Chunk->GetNeighborChunk(a_Location.x, a_Location.z); if ((Chunk == nullptr) || !Chunk->IsValid()) { + m_BadChunkFound = true; return true; } m_Chunk = Chunk; @@ -149,34 +168,29 @@ bool cPath::Step_Internal() { cPathCell * CurrentCell = OpenListPop(); - // Path not reachable, open list exauhsted. + // Path not reachable. if (CurrentCell == nullptr) { - FinishCalculation(ePathFinderStatus::PATH_NOT_FOUND); - ASSERT(m_Status == ePathFinderStatus::PATH_NOT_FOUND); + AttemptToFindAlternative(); return true; } // Path found. - if ( - (CurrentCell->m_Location == m_Destination + Vector3i(0, 0, 1)) || - (CurrentCell->m_Location == m_Destination + Vector3i(1, 0, 0)) || - (CurrentCell->m_Location == m_Destination + Vector3i(-1, 0, 0)) || - (CurrentCell->m_Location == m_Destination + Vector3i(0, 0, -1)) || - (CurrentCell->m_Location == m_Destination + Vector3i(0, -1, 0)) - ) + if (CurrentCell->m_Location == m_Destination) { - do - { - m_PathPoints.push_back(CurrentCell->m_Location); // Populate the cPath with points. - CurrentCell = CurrentCell->m_Parent; - } while (CurrentCell != nullptr); - + BuildPath(); FinishCalculation(ePathFinderStatus::PATH_FOUND); return true; } - // Calculation not finished yet, process a currentCell by inspecting all neighbors. + // Calculation not finished yet. + // Check if we have a new NearestPoint. + if (CurrentCell->m_H < m_NearestPointToTarget->m_H) + { + m_NearestPointToTarget = CurrentCell; + } + + // process a currentCell by inspecting all neighbors. // Check North, South, East, West on all 3 different heights. int i; @@ -213,6 +227,38 @@ bool cPath::Step_Internal() +void cPath::AttemptToFindAlternative() +{ + if (m_NearestPointToTarget == GetCell(m_Source)) + { + FinishCalculation(ePathFinderStatus::PATH_NOT_FOUND); + } + else + { + m_Destination = m_NearestPointToTarget->m_Location; + BuildPath(); + FinishCalculation(ePathFinderStatus::NEARBY_FOUND); + } +} + + + + + +void cPath::BuildPath() +{ + cPathCell * CurrentCell = GetCell(m_Destination); + do + { + m_PathPoints.push_back(CurrentCell->m_Location); // Populate the cPath with points. + CurrentCell = CurrentCell->m_Parent; + } while (CurrentCell != nullptr); +} + + + + + void cPath::FinishCalculation() { m_Map.clear(); @@ -225,6 +271,10 @@ void cPath::FinishCalculation() void cPath::FinishCalculation(ePathFinderStatus a_NewStatus) { + if (m_BadChunkFound) + { + a_NewStatus = ePathFinderStatus::PATH_NOT_FOUND; + } m_Status = a_NewStatus; FinishCalculation(); } @@ -250,7 +300,7 @@ cPathCell * cPath::OpenListPop() // Popping from the open list also means addin { if (m_OpenList.size() == 0) { - return nullptr; // We've exhausted the search space and nothing was found, this will trigger a PATH_NOT_FOUND status. + return nullptr; // We've exhausted the search space and nothing was found, this will trigger a PATH_NOT_FOUND or NEARBY_FOUND status. } cPathCell * Ret = m_OpenList.top(); diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index 008722d29..7a4182f17 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -23,7 +23,7 @@ Put this in your .cpp: class cChunk; /* Various little structs and classes */ -enum class ePathFinderStatus {CALCULATING, PATH_FOUND, PATH_NOT_FOUND}; +enum class ePathFinderStatus {CALCULATING, PATH_FOUND, PATH_NOT_FOUND, NEARBY_FOUND}; struct cPathCell; // Defined inside Path.cpp class compareHeuristics { @@ -62,9 +62,17 @@ public: /** Destroys the path and frees its memory. */ ~cPath(); - /** Performs part of the path calculation and returns true if the path computation has finished. */ + /** Performs part of the path calculation and returns the appropriate status. + If NEARBY_FOUND is returned, it means that the destination is not reachable, but a nearby destination + is reachable. If the user likes the alternative destination, they can call AcceptNearbyPath to treat the path as found, + and to make consequent calls to step return PATH_FOUND*/ ePathFinderStatus Step(cChunk & a_Chunk); + /** Called after the PathFinder's step returns NEARBY_FOUND. + Changes the PathFinder status from NEARBY_FOUND to PATH_FOUND, returns the nearby destination that + the PathFinder found a path to. */ + Vector3i AcceptNearbyPath(); + /* Point retrieval functions, inlined for performance. */ /** Returns the next point in the path. */ inline Vector3i GetNextPoint() @@ -93,7 +101,10 @@ public: /** Returns the total number of points this path has. */ inline int GetPointCount() { - ASSERT(m_Status == ePathFinderStatus::PATH_FOUND); + if (m_Status != ePathFinderStatus::PATH_FOUND) + { + return 0; + } return m_PathPoints.size(); } @@ -119,6 +130,8 @@ private: bool Step_Internal(); // The public version just calls this version * CALCULATIONS_PER_CALL times. void FinishCalculation(); // Clears the memory used for calculating the path. void FinishCalculation(ePathFinderStatus a_NewStatus); // Clears the memory used for calculating the path and changes the status. + void AttemptToFindAlternative(); + void BuildPath(); /* Openlist and closedlist management */ void OpenListAdd(cPathCell * a_Cell); @@ -135,6 +148,7 @@ private: Vector3i m_Destination; Vector3i m_Source; int m_StepsLeft; + cPathCell * m_NearestPointToTarget; /* Control fields */ ePathFinderStatus m_Status; @@ -145,6 +159,7 @@ private: /* Interfacing with the world */ cChunk * m_Chunk; // Only valid inside Step()! + bool m_BadChunkFound; #ifdef COMPILING_PATHFIND_DEBUGGER #include "../path_irrlicht.cpp" #endif -- cgit v1.2.3 From b9481dafeb0ded7b7544e47f0aa21e6f325350ab Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 17 May 2015 19:36:18 +0200 Subject: Updated the defaults for the overworld world generator --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index c0a79b9d0..ced459da8 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -800,7 +800,7 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) a_IniFile.GetValueSet("Generator", "BiomeGen", "Grown"); a_IniFile.GetValueSet("Generator", "ShapeGen", "BiomalNoise3D"); a_IniFile.GetValueSet("Generator", "CompositionGen", "Biomal"); - a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, NaturalPatches, PreSimulator, Animals"); + a_IniFile.GetValueSet("Generator", "Finishers", "RoughRavines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, TallGrass, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, NaturalPatches, PreSimulator, Animals"); break; } case dimNether: -- cgit v1.2.3 From 1f3f64fccd229a70b9f1b71cf4ecba8e764d98c9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 17 May 2015 22:33:43 +0200 Subject: APIDump: Removed an unneeded global variable. --- MCServer/Plugins/APIDump/main_APIDump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 4ca06b974..e841922b6 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -971,7 +971,7 @@ end --- Writes a list of undocumented objects into a file local function ListUndocumentedObjects(API, UndocumentedHooks) - f = io.open("API/_undocumented.lua", "w"); + local f = io.open("API/_undocumented.lua", "w"); if (f ~= nil) then f:write("\n-- This is the list of undocumented API objects, automatically generated by APIDump\n\n"); f:write("g_APIDesc =\n{\n\tClasses =\n\t{\n"); -- cgit v1.2.3 From a75106aea75080abb6d7180e88c573011a018357 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Mon, 18 May 2015 06:22:26 +0200 Subject: Fix the health of animals --- src/Generating/FinishGen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 00b34bddd..69ae59c18 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1274,6 +1274,7 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX double AnimalZ = static_cast(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ + 0.5); cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); + NewMob->SetHealth(NewMob->GetMaxHealth()); NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); a_ChunkDesc.GetEntities().push_back(NewMob); LOGD("Spawning %s #%i at {%.02f, %.02f, %.02f}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); -- cgit v1.2.3 From aedf9d05cb798e2ed3f9666028d12753929504fc Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 18 May 2015 13:32:47 +0100 Subject: Improved leaves a bit more. Should fix #2058. --- src/Blocks/BlockLeaves.h | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 8e44c94ac..4d4610fd8 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -40,29 +40,41 @@ public: { cFastRandom rand; - // Old leaves - 3 bits contain display; new leaves - 1st bit, shifted left two for saplings to understand - if (rand.NextInt(20) == 0) + // There is a chance to drop a sapling that varies depending on the type of leaf broken. + // TODO: Take into account fortune for sapling drops. + int chance; + if ((m_BlockType == E_BLOCK_LEAVES) && ((a_BlockMeta & 0x03) == E_META_LEAVES_JUNGLE)) + { + // Jungle leaves have a 2.5% chance of dropping a sapling. + chance = rand.NextInt(40); + } + else + { + // Other leaves have a 5% chance of dropping a sapling. + chance = rand.NextInt(20); + } + if (chance == 0) { a_Pickups.push_back( cItem( E_BLOCK_SAPLING, 1, - (m_BlockType == E_BLOCK_LEAVES) ? (a_BlockMeta & 0x03) : (2 << (a_BlockMeta & 0x01)) + (m_BlockType == E_BLOCK_LEAVES) ? (a_BlockMeta & 0x03) : (4 + (a_BlockMeta & 0x01)) ) ); } - - // 1 % chance of dropping an apple, if the leaves' type is Apple Leaves + + // 0.5 % chance of dropping an apple, if the leaves' type is Apple Leaves if ((m_BlockType == E_BLOCK_LEAVES) && ((a_BlockMeta & 0x03) == E_META_LEAVES_APPLE)) { - if (rand.NextInt(101) == 0) + if (rand.NextInt(200) == 0) { a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); } } } - - + + virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); -- cgit v1.2.3 From c2303ac4cf072f8e273ba9ddf72f5ef88c4baf13 Mon Sep 17 00:00:00 2001 From: tycho Date: Mon, 18 May 2015 15:43:26 +0100 Subject: Fix max slots logic to only override if acctually present. --- src/main.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a0f51105a..2cf4b383e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -373,12 +373,17 @@ std::unique_ptr parseArguments(int argc, char **argv) TCLAP::ValueArg slotsArg("s", "max-players", "Maximum number of slots for the server to use, overrides setting in setting.ini", false, -1, "number", cmd); cmd.parse(argc, argv); - - int slots = slotsArg.getValue(); auto repo = cpp14::make_unique(); - repo->SetValueI("Server", "MaxPlayers", slots); + if (slotsArg.isSet()) + { + + int slots = slotsArg.getValue(); + + repo->SetValueI("Server", "MaxPlayers", slots); + + } repo->SetReadOnly(); @@ -387,7 +392,7 @@ std::unique_ptr parseArguments(int argc, char **argv) catch (TCLAP::ArgException &e) { printf("error reading command line %s for arg %s", e.error().c_str(), e.argId().c_str()); - return nullptr; + return cpp14::make_unique(); } } -- cgit v1.2.3 From 2e98bfc4e98c1cb0730514628d501c2ca0326c4e Mon Sep 17 00:00:00 2001 From: tycho Date: Mon, 18 May 2015 16:04:27 +0100 Subject: Add support for setting ports through command line --- src/IniFile.cpp | 13 ++++++++++++- src/main.cpp | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 8dab87d15..cd98cce57 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -931,7 +931,18 @@ AStringVector ReadUpgradeIniPorts( ) { // Read the regular value, but don't use the default (in order to detect missing value for upgrade): - AStringVector Ports = StringSplitAndTrim(a_Settings.GetValue(a_KeyName, a_PortsValueName), ";,"); + + AStringVector Ports; + + for (auto pair : a_Settings.GetValues(a_KeyName)) + { + if (pair.first != a_PortsValueName) + { + continue; + } + AStringVector temp = StringSplitAndTrim(pair.second, ";,"); + Ports.insert(Ports.end(), temp.begin(), temp.end()); + } if (Ports.empty()) { diff --git a/src/main.cpp b/src/main.cpp index 2cf4b383e..8a237b8ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -372,6 +372,8 @@ std::unique_ptr parseArguments(int argc, char **argv) TCLAP::ValueArg slotsArg("s", "max-players", "Maximum number of slots for the server to use, overrides setting in setting.ini", false, -1, "number", cmd); + TCLAP::MultiArg portsArg("p", "port", "The port number the server should listen to", false, "port", cmd); + cmd.parse(argc, argv); auto repo = cpp14::make_unique(); @@ -381,8 +383,17 @@ std::unique_ptr parseArguments(int argc, char **argv) int slots = slotsArg.getValue(); - repo->SetValueI("Server", "MaxPlayers", slots); + repo->AddValue("Server", "MaxPlayers", static_cast(slots)); + + } + if (portsArg.isSet()) + { + std::vector ports = portsArg.getValue(); + for (auto port : ports) + { + repo->AddValue("Server", "Port", static_cast(port)); + } } repo->SetReadOnly(); -- cgit v1.2.3 From 4d4d1e9c69a15e154bc358f1363b961de80b27d6 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Mon, 18 May 2015 22:29:39 +0200 Subject: Added hooks HOOK_ENTITY_CHANGE_WORLD and HOOK_ENTITY_CHANGED_WORLD Fixes #1435. --- src/Bindings/Plugin.h | 2 ++ src/Bindings/PluginLua.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ src/Bindings/PluginLua.h | 2 ++ src/Bindings/PluginManager.cpp | 36 ++++++++++++++++++++++++++++++ src/Bindings/PluginManager.h | 4 ++++ src/Entities/Entity.cpp | 11 ++++++++++ src/Entities/Player.cpp | 10 +++++++++ 7 files changed, 115 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index d0c2bcefa..b4bbfd802 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -56,6 +56,8 @@ public: virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; + virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) = 0; + virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) = 0; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 76d3557a4..a8be26f71 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -534,6 +534,54 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E +bool cPluginLua::OnEntityChangeWorld(cEntity & a_Entity, cWorld & a_World) +{ + cCSLock Lock(m_CriticalSection); + if (!m_LuaState.IsValid()) + { + return false; + } + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGE_WORLD]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Entity, &a_World, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + +bool cPluginLua::OnEntityChangedWorld(cEntity & a_Entity, cWorld & a_World) +{ + cCSLock Lock(m_CriticalSection); + if (!m_LuaState.IsValid()) + { + return false; + } + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGED_WORLD]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Entity, &a_World, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) { cCSLock Lock(m_CriticalSection); @@ -1884,6 +1932,8 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect"; case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation"; case cPluginManager::HOOK_ENTITY_ADD_EFFECT: return "OnEntityAddEffect"; + case cPluginManager::HOOK_ENTITY_CHANGE_WORLD: return "OnEntityChangeWorld"; + case cPluginManager::HOOK_ENTITY_CHANGED_WORLD: return "OnEntityChangedWorld"; case cPluginManager::HOOK_ENTITY_TELEPORT: return "OnEntityTeleport"; case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand"; case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 524c249b0..533dc0331 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -115,6 +115,8 @@ public: virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; + virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) override; + virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) override; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index db2493955..cc74c8372 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -525,6 +525,42 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d & +bool cPluginManager::CallHookEntityChangeWorld(cEntity & a_Entity, cWorld & a_World) +{ + FIND_HOOK(HOOK_ENTITY_CHANGE_WORLD); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnEntityChangeWorld(a_Entity, a_World)) + { + return true; + } + } + return false; +} + + + + +bool cPluginManager::CallHookEntityChangedWorld(cEntity & a_Entity, cWorld & a_World) +{ + FIND_HOOK(HOOK_ENTITY_CHANGED_WORLD); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnEntityChangedWorld(a_Entity, a_World)) + { + return true; + } + } + return false; +} + + + + bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result) { FIND_HOOK(HOOK_EXECUTE_COMMAND); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index d8c886b62..2c3eaa75f 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -85,6 +85,8 @@ public: HOOK_DISCONNECT, HOOK_PLAYER_ANIMATION, HOOK_ENTITY_ADD_EFFECT, + HOOK_ENTITY_CHANGE_WORLD, + HOOK_ENTITY_CHANGED_WORLD, HOOK_EXECUTE_COMMAND, HOOK_EXPLODED, HOOK_EXPLODING, @@ -200,6 +202,8 @@ public: bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition); + bool CallHookEntityChangeWorld (cEntity & a_Entity, cWorld & a_World); + bool CallHookEntityChangedWorld (cEntity & a_Entity, cWorld & a_World); bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result); // If a_Player == nullptr, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 4a909a1fd..bc2b3e93e 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1403,14 +1403,25 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) return false; } + // Ask the plugins if the entity is allowed to change the world + if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World)) + { + // A Plugin doesn't allow the entity to change the world + return false; + } + // Remove all links to the old world SetWorldTravellingFrom(GetWorld()); // cChunk::Tick() handles entity removal GetWorld()->BroadcastDestroyEntity(*this); // Queue add to new world a_World->AddEntity(this); + cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD SetWorld(a_World); + // Entity changed the world, call the hook + cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld); + return true; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 607a663de..01ad26297 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1606,6 +1606,12 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) return false; } + if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World)) + { + // A Plugin doesn't allow the player to change the world + return false; + } + // Send the respawn packet: if (a_ShouldSendRespawn && (m_ClientHandle != nullptr)) { @@ -1621,6 +1627,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) // Queue adding player to the new world, including all the necessary adjustments to the object a_World->AddPlayer(this); + cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value // Update the view distance. @@ -1635,6 +1642,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) // Broadcast the player into the new world. a_World->BroadcastSpawnEntity(*this); + // Player changed the world, call the hook + cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld); + return true; } -- cgit v1.2.3 From 9aced8cd856eb66b7ff136cc77bca32cb4901354 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Tue, 19 May 2015 06:34:40 +0200 Subject: Added OnEntityChangeWorld.lua and OnEntityChangedWorld.lua hooks to APIDump --- .../Plugins/APIDump/Hooks/OnEntityChangeWorld.lua | 29 ++++++++++++++++++++++ .../Plugins/APIDump/Hooks/OnEntityChangedWorld.lua | 28 +++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua create mode 100644 MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua diff --git a/MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua b/MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua new file mode 100644 index 000000000..25072ca5c --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua @@ -0,0 +1,29 @@ +return +{ + HOOK_ENTITY_CHANGE_WORLD = + { + CalledWhen = "Before a entity is changing the world.", + DefaultFnName = "OnEntityChangeWorld", -- also used as pagename + Desc = [[ + This hook is called before the server moves the {{cEntity|entity}} to the given world. Plugins may + refuse the changing of the entity to the new world.

+ See also the {{OnEntityChangedWorld|HOOK_ENTITY_CHANGED_WORLD}} hook for a similar hook is called after the + entity has been moved to the world. + ]], + Params = + { + { Name = "Entity", Type = "{{cEntity}}", Notes = "The entity that wants to change the world" }, + { Name = "World", Type = "{{cWorld}}", Notes = "The world to which the entity wants to change" }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the change of the entity to the world is + cancelled. + ]], + }, -- HOOK_ENTITY_CHANGE_WORLD +} + + + + + diff --git a/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua b/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua new file mode 100644 index 000000000..00645c152 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua @@ -0,0 +1,28 @@ +return +{ + HOOK_ENTITY_CHANGED_WORLD = + { + CalledWhen = "After a entity has changed the world.", + DefaultFnName = "OnEntityChangedWorld", -- also used as pagename + Desc = [[ + This hook is called after the server has moved the {{cEntity|entity}} to the given world. This is an information-only + callback, the entity is already in the new world.

+ See also the {{OnEntityChangeWorld|HOOK_ENTITY_CHANGE_WORLD}} hook for a similar hook called before the + entity is moved to the new world. + ]], + Params = + { + { Name = "Entity", Type = "{{cEntity}}", Notes = "The entity that has changed the world" }, + { Name = "World", Type = "{{cWorld}}", Notes = "The world from which the entity has come" }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event. + ]], + }, -- HOOK_ENTITY_CHANGED_WORLD +} + + + + + -- cgit v1.2.3 From d1a0717a57a84dde634db57092120eb78f961751 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 19 May 2015 09:27:14 +0100 Subject: Improved contributor --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index a25c6f06b..21654428f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -7,6 +7,7 @@ Diusrex Duralex FakeTruth (founder) Howaner +jasperarmstrong keyboard Lapayo Luksor -- cgit v1.2.3 From d852209f8db9129a3d135a4f7034878d1438a57b Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 19 May 2015 09:29:27 +0100 Subject: Manual merge of #2066 --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index a29d67d15..2b00f6959 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -519,7 +519,7 @@ void cMonster::SetPitchAndYawFromDestination() double HeadRotation, HeadPitch; Distance.Normalize(); VectorToEuler(Distance.x, Distance.y, Distance.z, HeadRotation, HeadPitch); - if (abs(BodyRotation - HeadRotation) < 120) + if (std::abs(BodyRotation - HeadRotation) < 120) { SetHeadYaw(HeadRotation); SetPitch(-HeadPitch); -- cgit v1.2.3 From e7d948dc3c961e5e5ccd89217ff5709a37ba2ef6 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 19 May 2015 09:38:37 +0100 Subject: Removed tip4commit, it's not used anymore. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d013eff5..43ec942d5 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,7 @@ Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/maste Other Stuff ----------- -For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [Plugin API](http://mc-server.xoft.cz/LuaAPI/). - -Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) +For other stuff, including plugins and discussion, check out the [forums](http://forum.mc-server.org) and [Plugin API](http://mc-server.xoft.cz/LuaAPI/). Support Us on Gratipay: [![Support via Gratipay](http://img.shields.io/gittip/cuberite_team.svg)](https://www.gratipay.com/cuberite_team) -- cgit v1.2.3